From aec5759f82c28d296352b5c43f83c5bbeb8acd5e Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Tue, 28 May 2019 14:29:32 +0200 Subject: [PATCH 1/8] base class for all api objects handling request and parsing. --- gitea/gitea.py | 118 +++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index 22dbcee..457bb43 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -21,18 +21,57 @@ class NotFoundException(Exception): pass -class Organization: - """ Represents an Organization in the Gitea-instance. - Attr: - id: int - avatar_url: string - description: string - full_name: string - location: string - username: string - website: string - gitea: Gitea-instance. - """ + + +class GiteaApiObject: + + def __init__(self, gitea, id: int): + self.id = id + self.gitea = gitea + + def __repr__(self): + return "GiteaApiObject: %i" % (self.id) + + def __eq__(self, other): + return other.id == self.id if isinstance(other, type(self)) else False + + fields_to_parsers = {} + + @classmethod + def request(cls, gitea, id): + """Use for ginving a nice e.g. 'request(gita, orgname, repo, ticket)'. + All args are put into an args tuple for passing around""" + return cls._request(gitea, (id)) + + @classmethod + def _request(cls, gitea, args): + result = cls._get_gitea_api_object(gitea, args) + return cls.parse_request(gitea, result) + + @classmethod + def parse_request(cls, gitea, result): + id = int(result["id"]) + logging.debug("Found api object of type %s (id: %s)" % (type(cls), id)) + api_object = cls(gitea, id=id) + cls._initialize(api_object, result) + return api_object + + @classmethod + def _get_gitea_api_object(cls, gitea, args): + """Make the conctrete request to gitea-api""" + return {"id":args[0]} + + @classmethod + def _initialize(cls, api_object, result): + for i, v in result.items(): + if i in cls.fields_to_parsers: + parse_func = cls.fields_to_parsers[i] + setattr(api_object, i, parse_func(v)) + else: + setattr(api_object, i, v) + + +class Organization(GiteaApiObject): ORG_REQUEST = """/orgs/%s""" # ORG_REPOS_REQUEST = """/orgs/%s/repos""" # @@ -42,35 +81,22 @@ class Organization: ORG_GET_MEMBERS = """/orgs/%s/members""" # ORG_DELETE = """/orgs/%s""" # - def __init__(self, gitea, orgName: str, initJson: json = None): - """ Initialize Organization-Object. At least a name is required. - Will get this Organization, and fail if it does not exist. + def __init__(self, gitea, id: int): + super(Organization, self).__init__(gitea, id=id) - Args: - gitea (Gitea): current instance. - orgName: Name of Organization. - initJson (dict): Optional, init information for Organization + fields_to_parsers = { + "website": lambda t: t #just for demonstration purpose + } - Returns: Organization - The initialized Organization. + @classmethod + def request(cls, gitea, name): + return cls._request(gitea, (name)) - Throws: - NotFoundException - """ - self.gitea = gitea - self.username = "UNINIT" - self.__initialize_org(orgName, initJson) + @classmethod + def _get_gitea_api_object(cls, gitea, args): + return gitea.requests_get(cls.ORG_REQUEST % args) - def __repr__(self): - """ Representation of an Organization. Consisting of username and id. - """ - return "Organization: %s (%s)" % (self.username, self.id) - - def __eq__(self, other): - if not other is None: - if isinstance(other, Organization): - return other.id == self.id - return False + # oldstuff def get_repositories(self): """ Get the Repositories of this Organization. @@ -106,22 +132,6 @@ class Organization: results = self.gitea.requests_get(Organization.ORG_GET_MEMBERS % self.username) return [User(self, result["username"], initJson=result) for result in results] - def __initialize_org(self, orgName: str, result) -> None: - """ Initialize Organization. - - Args: - orgName (str): Name of the Organization - result (dict): Optional, init information for Organization - - Throws: - Exception, if Organization could not be found. - """ - if not result: - result = self.gitea.requests_get(Organization.ORG_REQUEST % orgName) - logging.debug("Found Organization: %s" % orgName) - for i, v in result.items(): - setattr(self, i, v) - def set_value(self, values: dict): """ Setting a certain value for an Organization. @@ -135,7 +145,7 @@ class Organization: result = self.gitea.requests_patch( Organization.ORG_PATCH % self.username, data=values ) - self.__initialize_org(self.username, result) + return Organization.create(self.gitea, result=result) def remove_member(self, username): if isinstance(username, User): From a4505ccba6fff095991d24b674d43ff757e21676 Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Tue, 28 May 2019 16:05:47 +0200 Subject: [PATCH 2/8] forgot updating Organization instanciation in one line --- gitea/gitea.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index 457bb43..b2a0044 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -145,7 +145,7 @@ class Organization(GiteaApiObject): result = self.gitea.requests_patch( Organization.ORG_PATCH % self.username, data=values ) - return Organization.create(self.gitea, result=result) + return Organization.parse_request(self.gitea, result) def remove_member(self, username): if isinstance(username, User): From 79c10de569612523d03898d0d3e97df79616ab13 Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Wed, 29 May 2019 14:42:11 +0200 Subject: [PATCH 3/8] refactored Repository --- gitea/gitea.py | 186 +++++++++++++------------------------------------ 1 file changed, 49 insertions(+), 137 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index b2a0044..791aaf0 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -6,23 +6,13 @@ from datetime import datetime logging = logging.getLogger("gitea") version = "0.4.4" - class AlreadyExistsException(Exception): - """ Something (User/Repo/Organization/...) already exists. - """ - pass - class NotFoundException(Exception): - """ Something (User/Repo/Organization/...) has not been found. - """ - pass - - class GiteaApiObject: def __init__(self, gitea, id: int): @@ -53,7 +43,7 @@ class GiteaApiObject: id = int(result["id"]) logging.debug("Found api object of type %s (id: %s)" % (type(cls), id)) api_object = cls(gitea, id=id) - cls._initialize(api_object, result) + cls._initialize(gitea, api_object, result) return api_object @classmethod @@ -62,11 +52,11 @@ class GiteaApiObject: return {"id":args[0]} @classmethod - def _initialize(cls, api_object, result): + def _initialize(cls, gitea, api_object, result): for i, v in result.items(): if i in cls.fields_to_parsers: parse_func = cls.fields_to_parsers[i] - setattr(api_object, i, parse_func(v)) + setattr(api_object, i, parse_func(gitea, v)) else: setattr(api_object, i, v) @@ -84,10 +74,6 @@ class Organization(GiteaApiObject): def __init__(self, gitea, id: int): super(Organization, self).__init__(gitea, id=id) - fields_to_parsers = { - "website": lambda t: t #just for demonstration purpose - } - @classmethod def request(cls, gitea, name): return cls._request(gitea, (name)) @@ -108,7 +94,7 @@ class Organization(GiteaApiObject): Organization.ORG_REPOS_REQUEST % self.username ) return [ - Repository(self.gitea, self, result["name"], initJson=result) + Repository.parse_request(self.gitea, result) for result in results ] @@ -130,7 +116,7 @@ class Organization(GiteaApiObject): A list of Users who are members of this Organization. """ results = self.gitea.requests_get(Organization.ORG_GET_MEMBERS % self.username) - return [User(self, result["username"], initJson=result) for result in results] + return [User.parse_request(self.gitea, result) for result in results] def set_value(self, values: dict): """ Setting a certain value for an Organization. @@ -164,18 +150,7 @@ class Organization(GiteaApiObject): self.gitea.requests_delete(Organization.ORG_DELETE % self.username) -class User: - """ Represents a User in the Gitea-instance. - - Attr: - avatar_url: string - email: string - full_name: string - id: int - is_admin: bool - language: string - login: string - """ +class User(GiteaApiObject): USER_MAIL = """/user/emails?sudo=%s""" # USER_REQUEST = """/users/%s""" # @@ -184,29 +159,17 @@ class User: ADMIN_DELETE_USER = """/admin/users/%s""" # USER_HEATMAP = """/users/%s/heatmap""" # - def __init__(self, gitea, userName: str, initJson: json = None): - """ Initialize a User. At least a username is necessary. + def __init__(self, gitea, id: int): + super(User, self).__init__(gitea, id=id) - Warning: - This will only get a user, not create one. - `Gitea.create_user` does that. + @classmethod + def request(cls, gitea, name): + return cls._request(gitea, (name)) - Args: - gitea (Gitea): current instance. - userName (str): login-name of the User. - initJson (dict): Optional, init information for User + @classmethod + def _get_gitea_api_object(cls, gitea, args): + return gitea.requests_get(cls.USER_REQUEST % args) - Throws: - NotFoundException, if User does not exist. - """ - self.gitea = gitea - self.username = "UNINIT" - self.__initialize_user(userName, initJson) - - def __repr__(self): - """ Representation of a User. Consisting of login-name and id. - """ - return "User: %s (%s)" % (self.login, self.id) def get_repositories(self): """ Get all Repositories owned by this User. @@ -214,26 +177,8 @@ class User: Returns: [Repository] A list of Repositories this user owns. """ - result = self.gitea.requests_get(User.USER_REPOS_REQUEST % self.username) - return [Repository(self.gitea, self, r["name"]) for r in result] - - def __initialize_user(self, userName: str, result) -> None: - """ Initialize User. - - Args: - userName (str): The name of the user. - result (dict): Optional, init information for User. - """ - if not result: - result = self.gitea.requests_get(User.USER_REQUEST % userName) - for i, v in result.items(): - setattr(self, i, v) - - def __eq__(self, other): - if other is not None: - if isinstance(other, User): - return other.id == self.id - return False + results = self.gitea.requests_get(User.USER_REPOS_REQUEST % self.username) + return [Repository.parse_request(self.gitea, result) for result in results] def update_mail(self): """ Update the mail of this user instance to one that is \ @@ -284,19 +229,7 @@ class User: return results -class Repository: - """ Represents a Repository in the Gitea-instance. - - Attr: - archived: bool - clone_url: string - default_branch: string - id: int - empty: bool - owner: User/Organization - private: bool - ... - """ +class Repository(GiteaApiObject): REPO_REQUEST = """/repos/%s/%s""" # , REPO_SEARCH = """/repos/search/%s""" # @@ -305,55 +238,21 @@ class Repository: REPO_DELETE = """/repos/%s/%s""" # , REPO_USER_TIME = """/repos/%s/%s/times/%s""" # , , - def __init__(self, gitea, repoOwner, repoName: str, initJson: json = None): - """ Initializing a Repository. + def __init__(self, gitea, id: int): + super(Repository, self).__init__(gitea, id=id) - Args: - gitea (Gitea): current instance. - repoOwner (User/Organization): Owner of the Repository. - repoName (str): Name of the Repository - initJson (dict): Optional, init information for Repository. + fields_to_parsers = { + "owner": lambda gitea, r: User.parse_request(gitea, r), + "updated_at": lambda gitea, t: Util.convert_time(t) + } - Warning: - This does not Create a Repository. `gitea.create_repo` does. + @classmethod + def request(cls, gitea, name): + return cls._request(gitea, (name)) - Throws: - NotFoundException, if Repository has not been found. - """ - self.gitea = gitea - self.name = "UNINIT" - self.__initialize_repo(repoOwner, repoName, initJson) - - def __initialize_repo(self, repoOwner, repoName: str, result): - """ Initializing a Repository. - - Args: - repoOwner (User/Organization): Owner of the Repository - repoName (str): Name of the Repository - result (dict): Optional, init information for Repository. - - Throws: - NotFoundException, if Repository has not been found. - """ - if not result: - result = self.gitea.requests_get( - Repository.REPO_REQUEST % (repoOwner.username, repoName) - ) - logging.debug("Found Repository: %s/%s" % (repoOwner.username, repoName)) - for i, v in result.items(): - setattr(self, i, v) - self.owner = repoOwner - - def __eq__(self, other): - if not other is None: - if isinstance(other, Repository): - return other.id == self.id - return False - - def __repr__(self): - """ Representation of a Repository. Consisting of path and id. - """ - return "Repository: %s/%s (%s)" % (self.owner.username, self.name, self.id) + @classmethod + def _get_gitea_api_object(cls, gitea, args): + return gitea.requests_get(cls.REPO_REQUEST % args) def get_branches(self): """Get all the Branches of this Repository. @@ -729,7 +628,7 @@ class Team: """ results = self.gitea.requests_get(Team.GET_MEMBERS % self.id) return [ - User(self.gitea, result["username"], initJson=result) for result in results + User.parse_request(self.gitea, result) for result in results ] def get_repos(self): @@ -740,7 +639,7 @@ class Team: """ results = self.gitea.requests_get(Team.GET_REPOS % self.id) return [ - Repository(self.gitea, self.organization, result["name"], initJson=result) + Repository.parse_request(self.gitea, result) for result in results ] @@ -750,6 +649,19 @@ class Team: self.gitea.requests_delete(Team.TEAM_DELETE % self.id) + +class Util: + + @staticmethod + def convert_time(time: str) -> datetime: + """ + Gitea returns time in the formt "%Y-%m-%dT%H:%M:%S:%z" but with ":" in time zone notation. + This is a somewhat hacky solution. + """ + return datetime.strptime( + time[:-3] + "00", "%Y-%m-%dT%H:%M:%S%z" + ) + class Gitea: """ Has Gitea-authenticated session. Can Create Users/Organizations/Teams/... @@ -1067,9 +979,9 @@ class Gitea: # # # - def get_user(self) -> User: + def get_user(self): result = self.requests_get(Gitea.GET_USER) - return User(self, "UNINIT", initJson=result) + return User.parse_request(self, result) def get_version(self) -> str: result = self.requests_get(Gitea.GITEA_VERSION) @@ -1083,7 +995,7 @@ class Gitea: change_pw=True, sendNotify=True, sourceId=0, - ) -> User: + ): """ Create User. Args: @@ -1121,7 +1033,7 @@ class Gitea: else: logging.error(result["message"]) raise Exception("User not created... (gitea: %s)" % result["message"]) - return User(self, userName, result) + return User.parse_request(self, result) def create_repo( self, @@ -1174,7 +1086,7 @@ class Gitea: else: logging.error(result["message"]) raise Exception("Repository not created... (gitea: %s)" % result["message"]) - return Repository(self, repoOwner, repoName, result) + return Repository.parse_request(self, result) def create_org( self, From 4753641296fbf7806339e2f18d652f85838bc75c Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Wed, 29 May 2019 17:37:03 +0200 Subject: [PATCH 4/8] cont. --- gitea/gitea.py | 183 ++++++++++++++----------------------------------- 1 file changed, 53 insertions(+), 130 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index 791aaf0..f709106 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -15,6 +15,8 @@ class NotFoundException(Exception): class GiteaApiObject: + GET_API_OBJECT = "FORMAT/STINING/{argument}" + def __init__(self, gitea, id: int): self.id = id self.gitea = gitea @@ -25,18 +27,25 @@ class GiteaApiObject: def __eq__(self, other): return other.id == self.id if isinstance(other, type(self)) else False + def __hash__(self): + return self.id + fields_to_parsers = {} @classmethod def request(cls, gitea, id): """Use for ginving a nice e.g. 'request(gita, orgname, repo, ticket)'. All args are put into an args tuple for passing around""" - return cls._request(gitea, (id)) + return cls._request(gitea, {"id":id}) @classmethod def _request(cls, gitea, args): result = cls._get_gitea_api_object(gitea, args) - return cls.parse_request(gitea, result) + api_object = cls.parse_request(gitea, result) + api_object = cls.parse_request(gitea, result) + for key, value in args.items(): # hack: not all necessary request args in api result (e.g. repo name in issue) + setattr(api_object, key, value) + return api_object @classmethod def parse_request(cls, gitea, result): @@ -48,22 +57,23 @@ class GiteaApiObject: @classmethod def _get_gitea_api_object(cls, gitea, args): - """Make the conctrete request to gitea-api""" - return {"id":args[0]} + """Retrieving an object always as GET_API_OBJECT """ + return gitea.requests_get(cls.GET_API_OBJECT.format(**args)) @classmethod def _initialize(cls, gitea, api_object, result): for i, v in result.items(): - if i in cls.fields_to_parsers: + if i in cls.fields_to_parsers and v is not None: parse_func = cls.fields_to_parsers[i] setattr(api_object, i, parse_func(gitea, v)) else: setattr(api_object, i, v) + class Organization(GiteaApiObject): - ORG_REQUEST = """/orgs/%s""" # + GET_API_OBJECT = """/orgs/{name}""" # ORG_REPOS_REQUEST = """/orgs/%s/repos""" # ORG_TEAMS_REQUEST = """/orgs/%s/teams""" # ORG_TEAMS_CREATE = """/orgs/%s/teams""" # @@ -76,11 +86,8 @@ class Organization(GiteaApiObject): @classmethod def request(cls, gitea, name): - return cls._request(gitea, (name)) + return cls._request(gitea, {"name": name}) - @classmethod - def _get_gitea_api_object(cls, gitea, args): - return gitea.requests_get(cls.ORG_REQUEST % args) # oldstuff @@ -152,8 +159,8 @@ class Organization(GiteaApiObject): class User(GiteaApiObject): + GET_API_OBJECT = """/users/{name}""" # USER_MAIL = """/user/emails?sudo=%s""" # - USER_REQUEST = """/users/%s""" # USER_REPOS_REQUEST = """/users/%s/repos""" # USER_PATCH = """/admin/users/%s""" # ADMIN_DELETE_USER = """/admin/users/%s""" # @@ -164,11 +171,7 @@ class User(GiteaApiObject): @classmethod def request(cls, gitea, name): - return cls._request(gitea, (name)) - - @classmethod - def _get_gitea_api_object(cls, gitea, args): - return gitea.requests_get(cls.USER_REQUEST % args) + return cls._request(gitea, {"name": name}) def get_repositories(self): @@ -231,7 +234,7 @@ class User(GiteaApiObject): class Repository(GiteaApiObject): - REPO_REQUEST = """/repos/%s/%s""" # , + GET_API_OBJECT = """/repos/{owner}/{name}""" # , REPO_SEARCH = """/repos/search/%s""" # REPO_BRANCHES = """/repos/%s/%s/branches""" # , REPO_ISSUES = """/repos/%s/%s/issues""" # @@ -247,12 +250,8 @@ class Repository(GiteaApiObject): } @classmethod - def request(cls, gitea, name): - return cls._request(gitea, (name)) - - @classmethod - def _get_gitea_api_object(cls, gitea, args): - return gitea.requests_get(cls.REPO_REQUEST % args) + def request(cls, gitea, owner, name): + return cls._request(gitea, {"owner": owner, "name": name}) def get_branches(self): """Get all the Branches of this Repository. @@ -291,7 +290,12 @@ class Repository(GiteaApiObject): if len(results) <= 0: break index += 1 - issues += [Issue(self, result["id"], result) for result in results] + for result in results: + issue = Issue.parse_request(self.gitea, result) + #again a hack because this infomation gets lost after the api call + setattr(issue, "repo", self.name) + setattr(issue, "owner", self.owner.username) + issues.append(issue) return issues def get_user_time(self, username, ignore_above=8): @@ -330,128 +334,47 @@ class Repository(GiteaApiObject): ) -class Milestone: +class Milestone(GiteaApiObject): """Reperesents a Milestone in Gitea. """ - GET = """/repos/%s/%s/milestones/%s""" # + GET_API_OBJECT = """/repos/{owner}/{repo}/milestones/{number}""" # - def __init__(self, repo: Repository, id: int, initJson: json = None): - """ Initializes a Milestone. + def __init__(self, gitea, id: int): + super(Milestone, self).__init__(gitea, id=id) - Args: - repo (Repository): The Repository of this Milestone. - id (int): The id of the Milestone. - initJson (dict): Optional, init information for Milestone. - - Warning: - This does not create a Milestone. does. - - Throws: - NotFoundException, if the Milestone could not be found. - """ - self.gitea = repo.gitea - self.__initialize_milestone(repo, id, initJson) - - def __initialize_milestone(self, repository, id, result): - """ Initializes a Milestone. - - Args: - repo (Repository): The Repository of this Milestone. - id (int): The id of the Milestone. - initJson (dict): Optional, init information for Milestone. - - Throws: - NotFoundException, if the Milestone could not be found. - """ - if not result: - result = self.gitea.requests_get( - Milestone.GET % (repository.owner.username, repository.name, id) - ) - logging.debug( - "Milestone found: %s/%s/%s: %s" - % (repository.owner.username, repository.name, id, result["title"]) - ) - for i, v in result.items(): - setattr(self, i, v) - self.repository = repository - - def __eq__(self, other): - if other is not None: - if isinstance(other, Milestone): - return other.id == self.id - return False - - def __hash__(self): - return self.id - - def __repr__(self): - return "Milestone: '%s'" % self.title + @classmethod + def request(cls, gitea, owner, repo, number): + return cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) def full_print(self): return str(vars(self)) -class Issue: - """Reperestents an Issue in Gitea. - """ +class Issue(GiteaApiObject): - GET = """/repos/%s/%s/issues/%s""" # + GET_API_OBJECT = """/repos/{owner}/{repo}/issues/{number}""" # GET_TIME = """/repos/%s/%s/issues/%s/times""" # - def __init__(self, repo: Repository, id: int, initJson: json = None): - """ Initializes a Issue. + closed = "closed" + open = "open" - Args: - repo (Repository): The Repository of this Issue. - id (int): The id of the Issue. - initJson (dict): Optional, init information for Issue. + def __init__(self, gitea, id: int): + super(Issue, self).__init__(gitea, id=id) - Warning: - This does not create an Issue. does. + fields_to_parsers = { + "milestone": lambda gitea, m: Milestone.parse_request(gitea, m), + "user": lambda gitea, u: User.parse_request(gitea, u), + "assignee": lambda gitea, u: User.parse_request(gitea, u), + "assignees": lambda gitea, us: [User.parse_request(gitea, u) for u in us], + "state": lambda gitea, s: Issue.closed if s == "closed" else Issue.open + } - Throws: - NotFoundException, if the Issue could not be found. - """ - self.gitea = repo.gitea - self.__initialize_issue(repo, id, initJson) + @classmethod + def request(cls, gitea, owner, repo, number): + api_object = cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) + return api_object - def __initialize_issue(self, repository, id, result): - """ Initializing an Issue. - - Args: - repo (Repository): The Repository of this Issue. - id (int): The id of the Issue. - initJson (dict): Optional, init information for Issue. - - Throws: - NotFoundException, if the Issue could not be found. - """ - if not result: - result = self.gitea.requests_get( - Issue.GET % (repository.owner.username, repository.name, id) - ) - logging.debug( - "Issue found: %s/%s/%s: %s" - % (repository.owner.username, repository.name, id, result["title"]) - ) - for i, v in result.items(): - setattr(self, i, v) - self.repository = repository - self.milestone = ( - Milestone(repository, self.milestone["id"], self.milestone) - if self.milestone - else self.milestone - ) - - def __eq__(self, other): - if other is not None: - if isinstance(other, Milestone): - return other.id == self.id - return False - - def __repr__(self): - return "#%i %s" % (self.id, self.title) def get_estimate_sum(self): """Returns the summed estimate-labeled values""" @@ -467,7 +390,7 @@ class Issue: return sum( (t["time"] // 60) / 60 for t in self.gitea.requests_get( - Issue.GET_TIME % (self.repository.owner.username, self.repository.name, self.number) + Issue.GET_TIME % (self.owner, self.repo, self.number) ) if user_id and t["user_id"] == user_id ) From f8159771ef2237c3f3c646d2f627f2e96cb59f8f Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Tue, 11 Jun 2019 00:27:37 +0200 Subject: [PATCH 5/8] renamed tests.py to usual naming for test files; restoring tests for api refactor --- gitea/gitea.py | 166 ++++++++++-------------------------------------- test_api.py | 122 +++++++++++++++++++++++++++++++++++ tests.py | 169 ------------------------------------------------- 3 files changed, 155 insertions(+), 302 deletions(-) create mode 100644 test_api.py delete mode 100644 tests.py diff --git a/gitea/gitea.py b/gitea/gitea.py index f709106..8bc98a1 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -21,9 +21,6 @@ class GiteaApiObject: self.id = id self.gitea = gitea - def __repr__(self): - return "GiteaApiObject: %i" % (self.id) - def __eq__(self, other): return other.id == self.id if isinstance(other, type(self)) else False @@ -42,9 +39,9 @@ class GiteaApiObject: def _request(cls, gitea, args): result = cls._get_gitea_api_object(gitea, args) api_object = cls.parse_request(gitea, result) - api_object = cls.parse_request(gitea, result) for key, value in args.items(): # hack: not all necessary request args in api result (e.g. repo name in issue) - setattr(api_object, key, value) + if not hasattr(api_object, key): + setattr(api_object, key, value) return api_object @classmethod @@ -70,7 +67,6 @@ class GiteaApiObject: setattr(api_object, i, v) - class Organization(GiteaApiObject): GET_API_OBJECT = """/orgs/{name}""" # @@ -88,7 +84,6 @@ class Organization(GiteaApiObject): def request(cls, gitea, name): return cls._request(gitea, {"name": name}) - # oldstuff def get_repositories(self): @@ -114,7 +109,7 @@ class Organization(GiteaApiObject): results = self.gitea.requests_get( Organization.ORG_TEAMS_REQUEST % self.username ) - return [Team(self, result["name"], initJson=result) for result in results] + return [Team.parse_request(self, result) for result in results] def get_members(self): """ Get all members of this Organization @@ -245,7 +240,8 @@ class Repository(GiteaApiObject): super(Repository, self).__init__(gitea, id=id) fields_to_parsers = { - "owner": lambda gitea, r: User.parse_request(gitea, r), + # dont know how to tell apart user and org as owner except form email being empty. + "owner": lambda gitea, r: Organization.parse_request(gitea,r) if r["email"] == "" else User.parse_request(gitea, r), "updated_at": lambda gitea, t: Util.convert_time(t) } @@ -262,7 +258,7 @@ class Repository(GiteaApiObject): results = self.gitea.requests_get( Repository.REPO_BRANCHES % (self.owner.username, self.name) ) - return [Branch(self, result["name"], result) for result in results] + return [Branch.parse_request(self.gitea, result) for result in results] def get_issues(self): """Get all Issues of this Repository. @@ -335,14 +331,17 @@ class Repository(GiteaApiObject): class Milestone(GiteaApiObject): - """Reperesents a Milestone in Gitea. - """ GET_API_OBJECT = """/repos/{owner}/{repo}/milestones/{number}""" # def __init__(self, gitea, id: int): super(Milestone, self).__init__(gitea, id=id) + fields_to_parsers = { + "closed_at": lambda gitea, t: Util.convert_time(t), + "due_on": lambda gitea, t: Util.convert_time(t) + } + @classmethod def request(cls, gitea, owner, repo, number): return cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) @@ -396,119 +395,37 @@ class Issue(GiteaApiObject): ) -class Branch: - """ Represents a Branch in the Gitea-instance. +class Branch(GiteaApiObject): - Attr: - name: string - commit: Commit - """ + GET_API_OBJECT = """/repos/%s/%s/branches/%s""" # , , - REPO_BRANCH = """/repos/%s/%s/branches/%s""" # , , + def __init__(self, gitea, id: int): + super(Branch, self).__init__(gitea, id=id) - def __init__(self, repo: Repository, name: str, initJson: json = None): - """ Initializes a Branch. - - Args: - repo (Repository): The Repository of this Branch. - name (str): The name of this Branch. - initJson (dict): Optional, init information for Branch. - - Warning: - This does not create a Branch. does. - - Throws: - NotFoundException, if Branch could not be found. - """ - self.gitea = repo.gitea - self.__initialize_branch(repo, name, initJson) - - def __initialize_branch(self, repository, name, result): - """ Initializing a Branch. - - Args: - repository (Repository): The Repository of this Branch. - name (str): The name of this Branch. - result (dict): Optional, init information for Branch. - - Throws: - NotFoundException, if Branch could not be found. - """ - if not result: - result = self.gitea.requests_get( - Branch.REPO_BRANCH % (repository.owner.username, repository.name, name) - ) - logging.debug( - "Branch found: %s/%s/%s" - % (repository.owner.username, repository.name, name) - ) - for i, v in result.items(): - setattr(self, i, v) - self.repository = repository + @classmethod + def request(cls, gitea, owner, repo, ref): + return cls._request(gitea, {"owner":owner, "repo":repo, "ref":ref}) -class Team: - """ Represents a Team in the Gitea-instance. - """ +class Team(GiteaApiObject): - # GET_TEAM = """/orgs/%s/teams""" - GET_TEAM = """/teams/%s""" # + GET_API_OBJECT = """/teams/{id}""" # ADD_USER = """/teams/%s/members/%s""" # ADD_REPO = """/teams/%s/repos/%s/%s""" # TEAM_DELETE = """/teams/%s""" # GET_MEMBERS = """/teams/%s/members""" # GET_REPOS = """/teams/%s/repos""" # - def __init__(self, org: Organization, name: str, initJson: json = None): - """ Initializes Team. + def __init__(self, gitea, id: int): + super(Team, self).__init__(gitea, id=id) - Args: - org (Organization): Organization this team is part of. - name (str): Name of the Team. - initJson (dict): Optional, init information for Team. + fields_to_parsers = { + "organization": lambda gitea, o: Organization.parse_request(gitea, o) + } - Warning: - This does not create a Team. `gitea.create_team` does. - - Throws: - NotFoundException, if Team could not be found. - """ - self.gitea = org.gitea - self.__initialize_team(org, name, initJson) - - def __initialize_team(self, org, name, result): - """ Initializes Team. - - Args: - org (Organization): Organization this team is part of. - name (str): Name of the Team. - result (dict): Optional, init information for Team. - - Throws: - NotFoundException, if Team could not be found. - """ - if not result: - for team in org.get_teams(): - if team.name == name: - result = self.gitea.requests_get(Team.GET_TEAM % team.id) - logging.debug("Team found: %s/%s" % (org.username, name)) - if not result: - logging.warning("Failed to find Team: %s/%s" % (org.username, name)) - raise NotFoundException("Team could not be Found") - for i, v in result.items(): - setattr(self, i, v) - self.organization = org - - def __repr__(self): - """ Representation of a Team. Consisting of name and id. - """ - return "Team: %s/%s (%s)" % (self.organization.username, self.name, self.id) - - def __eq__(self, other): - if other is not None: - if isinstance(other, Team): - return other.id == self.id - return False + @classmethod + def request(cls, gitea, id): + return cls._request(gitea, {"id":id}) def add(self, toAdd): """ Adding User or Repository to Team. @@ -572,7 +489,6 @@ class Team: self.gitea.requests_delete(Team.TEAM_DELETE % self.id) - class Util: @staticmethod @@ -968,7 +884,7 @@ class Gitea: gitignores=None, license=None, readme="Default", - ) -> Repository: + ): """ Create a Repository. Args: @@ -1019,24 +935,8 @@ class Gitea: location="", website="", full_name="", - ) -> Organization: - """ Creates Organization. + ): - Args: - owner (User): The User that will own this Organization. - orgName (str): The name of the new Organization. - description (str): Short description of the Organization. - location (str): Optional, where the Organization is located. - website (str): Optional, a website of this Organization. - full_name (str): Optional, the full name of the Organization. - - Returns: Organization - The newly created Organization. - - Throws: - AlreadyExistsException, if this Organization already exists. - Exception, if something else went wrong. - """ assert isinstance(owner, User) result = self.requests_post( Gitea.CREATE_ORG % owner.username, @@ -1056,7 +956,7 @@ class Gitea: raise Exception( "Organization not created... (gitea: %s)" % result["message"] ) - return Organization(self, orgName, initJson=result) + return Organization.parse_request(self, result) def create_team( self, @@ -1073,7 +973,7 @@ class Gitea: "repo.releases", "repo.ext_wiki", ], - ) -> Team: + ): """ Creates a Team. Args: @@ -1097,4 +997,4 @@ class Gitea: logging.error("Team not created... (gitea: %s)" % result["message"]) logging.error(result["message"]) raise Exception("Team not created... (gitea: %s)" % result["message"]) - return Team(org, name, initJson=result) + return Team.parse_request(self, result) diff --git a/test_api.py b/test_api.py new file mode 100644 index 0000000..3fc77e3 --- /dev/null +++ b/test_api.py @@ -0,0 +1,122 @@ +import os + +import pytest +import uuid + +from .gitea import Gitea, User, Organization, Team, Repository, version +from .gitea import NotFoundException, AlreadyExistsException + +assert version >= "0.4.0" +gitea = None + +# put a ".token" file into your directory containg only the token for gitea +try: + gitea = Gitea("http://localhost:3000", open(".token", "r").read().strip()) + print("Gitea Version: " + gitea.get_version()) + print("API-Token belongs to user: " + gitea.get_user().username) +except: + assert ( + False + ), "Gitea could not load. \ + - Instance running at http://localhost:3000 \ + - Token at .token \ + ?" + +#make up some fresh names for the test run +test_org = "org_" + uuid.uuid4().hex[:8] +test_user = "user_" +uuid.uuid4().hex[:8] +test_team = "team_" +uuid.uuid4().hex[:8] # team names seem to have a rather low max lenght +test_repo = "repo_" +uuid.uuid4().hex[:8] + +def test_token_owner(): + assert gitea.get_user().username == "test", "Token user not 'test'." + +def test_gitea_version(): + assert gitea.get_version() == "1.8.0", "Version changed. Updated?" + +def test_fail_get_non_existent_user(): + with pytest.raises(NotFoundException) as e: + User.request(gitea, test_user) + +def test_fail_get_non_existent_org(): + with pytest.raises(NotFoundException) as e: + Organization.request(gitea, test_org) + +def test_fail_get_non_existent_repo(): + with pytest.raises(NotFoundException) as e: + Repository.request(gitea, test_user, test_repo) + +def test_create_user(): + email = test_user + "@example.org" + user = gitea.create_user(test_user, email, "abcdefg123") + user.update_mail() + assert user.username == test_user + assert user.login == test_user + assert user.email == email + assert not user.is_admin + +def test_create_org(): + user = gitea.get_user() + org = gitea.create_org(user, test_org, "some-desc", "loc") + assert org.get_members() == [user] + assert org.description == "some-desc" + assert org.username == test_org + assert org.location == "loc" + assert not org.website + assert not org.full_name + +def test_create_repo_userowned(): + org = User.request(gitea, test_user) + repo = gitea.create_repo(org, test_repo, "user owned repo") + assert repo.description == "user owned repo" + assert repo.owner == org + assert repo.name == test_repo + assert not repo.private + +def test_create_repo_orgowned(): + org = Organization.request(gitea, test_org) + repo = gitea.create_repo(org, test_repo, "descr") + assert repo.description == "descr" + assert repo.owner == org + assert repo.name == test_repo + assert not repo.private + +def test_create_team(): + org = Organization.request(gitea, test_org) + team = gitea.create_team(org, test_team, "descr") + assert team.name == test_team + assert team.description == "descr" + assert team.organization == org + +def test_delete_repo_userowned(): + org = User.request(gitea, test_user) + repo = Repository.request(gitea, org.username, test_repo) + repo.delete() + with pytest.raises(NotFoundException) as e: + Repository.request(gitea, test_user, test_repo) + +def test_delete_repo_orgowned(): + org = Organization.request(gitea, test_org) + repo = Repository.request(gitea, org.username, test_repo) + repo.delete() + with pytest.raises(NotFoundException) as e: + Repository.request(gitea, test_user, test_repo) + +def test_delete_team(): + org = Organization.request(gitea, test_org) + team = Team.request(org, test_team) + team.delete() + with pytest.raises(NotFoundException) as e: + Team(org, test_team) + +def test_delete_org(): + org = Organization.request(gitea, test_org) + org.delete() + with pytest.raises(NotFoundException) as e: + Organization.request(gitea, test_org) + +def test_delete_user(): + user = User.request(gitea, test_user) + user.delete() + with pytest.raises(NotFoundException) as e: + User.request(gitea, test_user) \ No newline at end of file diff --git a/tests.py b/tests.py deleted file mode 100644 index bf3c3a4..0000000 --- a/tests.py +++ /dev/null @@ -1,169 +0,0 @@ -import os - -from gitea import Gitea, User, Organization, Team, Repository, version -from gitea import NotFoundException, AlreadyExistsException - -assert version >= "0.4.0" - - -# Testing a localhost instance for API-functionality. -# - - -# testing includes: -# - reading in token -# - creation of organization -# - creation of repository -# - creation of team -# - creation of user -# - assigning team to repository -# - assigning user to team -# - deleting created user -# - deleting repository -# - deleting team -# - deleting organization - - -def expect_not_exist(fn, expect) -> bool: - try: - fn() - return False - except expect: - return True - - -gitea = None - -# put a ".token" file into your directory containg only the token for gitea -try: - gitea = Gitea("http://localhost:3000", open(".token", "r").read().strip()) - print("Gitea Version: " + gitea.get_version()) - print("API-Token belongs to user: " + gitea.get_user().username) -except: - assert ( - False - ), "Gitea could not load. \ - - Instance running at http://localhost:3000 \ - - Token at .token \ - ?" - - -def test_token(): - assert gitea.get_user().username == "test", "Token user not 'test'." - - -def test_version(): - assert gitea.get_version() == "1.8.0-rc2", "Version changed. Updated?" - - -def test_before_user(): - # This should not work currently - assert expect_not_exist( - lambda: User(gitea, "test-user"), (NotFoundException) - ), "User test-user should not exist" - - -def test_before_org(): - assert expect_not_exist( - lambda: Organization(gitea, "test-org"), (NotFoundException) - ), "Organization test-org should not exist" - - -def test_before_repo(): - assert expect_not_exist( - lambda: Repository(gitea, User(gitea, "test-user"), "test-repo"), - (NotFoundException), - ), "Repository test-repo should not exist" - - -def test_before_team(): - assert expect_not_exist( - lambda: Team(gitea, Organization(gitea, "test-org"), "test-team"), - (NotFoundException), - ), "Team test-team should not exist" - - -def test_create_user(): - user = gitea.create_user("test-user", "testmail@example.org", "pw1234") - user.update_mail() - assert user.username == "test-user" - assert user.login == "test-user" - assert user.email == "testmail@example.org" - assert not user.is_admin - - -def test_create_org(): - user = gitea.get_user() - org = gitea.create_org(user, "test-org", "some-desc", "loc") - assert org.get_members() == [user] - assert org.description == "some-desc" - assert org.username == "test-org" - assert org.location == "loc" - assert not org.website - assert not org.full_name - - -def test_create_repo(): - org = Organization(gitea, "test-org") - repo = gitea.create_repo(org, "test-repo", "descr") - assert repo.description == "descr" - assert repo.owner == org - assert repo.name == "test-repo" - assert not repo.private - - -def test_create_team(): - org = Organization(gitea, "test-org") - team = gitea.create_team(org, "test-team", "descr") - assert team.name == "test-team" - assert team.description == "descr" - assert team.organization == org - - -def test_full(): - user = User(gitea, "test-user") - user.update_mail() - org = Organization(gitea, "test-org") - team = Team(org, "test-team") - assert team.get_members() == [] - team.add(user) - assert team.get_members() == [user] - repo = Repository(gitea, org, "test-repo") - assert team.get_repos() == [] - team.add(repo) - assert team.get_repos() == [repo] - - -def test_delete_repo(): - org = Organization(gitea, "test-org") - repo = Repository(gitea, org, "test-repo") - repo.delete() - assert expect_not_exist( - lambda: Repository(gitea, User(gitea, "test-user"), "test-repo"), - (NotFoundException), - ), "Repository test-repo should not exist" - - -def test_delete_team(): - org = Organization(gitea, "test-org") - team = Team(org, "test-team") - team.delete() - assert expect_not_exist( - lambda: Team(org, "test-team"), (NotFoundException) - ), "Team test-team should not exist" - - -def test_delete_org(): - org = Organization(gitea, "test-org") - org.delete() - assert expect_not_exist( - lambda: Organization(gitea, "test-org"), (NotFoundException) - ), "Organization test-org should not exist" - - -def test_delete_user(): - user = User(gitea, "test-user") - user.delete() - assert expect_not_exist( - lambda: User(gitea, "test-user"), (NotFoundException) - ), "User test-user should not exist" From 2720950c2551532f48c9e2afa20982ed11392781 Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Tue, 11 Jun 2019 21:36:18 +0200 Subject: [PATCH 6/8] small fix to get team setup working again --- gitea/gitea.py | 21 ++++++++++++--------- test_api.py | 40 ++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index 8bc98a1..f51c901 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -30,7 +30,7 @@ class GiteaApiObject: fields_to_parsers = {} @classmethod - def request(cls, gitea, id): + def get(cls, gitea, id): """Use for ginving a nice e.g. 'request(gita, orgname, repo, ticket)'. All args are put into an args tuple for passing around""" return cls._request(gitea, {"id":id}) @@ -81,7 +81,7 @@ class Organization(GiteaApiObject): super(Organization, self).__init__(gitea, id=id) @classmethod - def request(cls, gitea, name): + def get(cls, gitea, name): return cls._request(gitea, {"name": name}) # oldstuff @@ -165,7 +165,7 @@ class User(GiteaApiObject): super(User, self).__init__(gitea, id=id) @classmethod - def request(cls, gitea, name): + def get(cls, gitea, name): return cls._request(gitea, {"name": name}) @@ -246,7 +246,7 @@ class Repository(GiteaApiObject): } @classmethod - def request(cls, gitea, owner, name): + def get(cls, gitea, owner, name): return cls._request(gitea, {"owner": owner, "name": name}) def get_branches(self): @@ -343,7 +343,7 @@ class Milestone(GiteaApiObject): } @classmethod - def request(cls, gitea, owner, repo, number): + def get(cls, gitea, owner, repo, number): return cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) def full_print(self): @@ -370,7 +370,7 @@ class Issue(GiteaApiObject): } @classmethod - def request(cls, gitea, owner, repo, number): + def get(cls, gitea, owner, repo, number): api_object = cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) return api_object @@ -403,7 +403,7 @@ class Branch(GiteaApiObject): super(Branch, self).__init__(gitea, id=id) @classmethod - def request(cls, gitea, owner, repo, ref): + def get(cls, gitea, owner, repo, ref): return cls._request(gitea, {"owner":owner, "repo":repo, "ref":ref}) @@ -424,7 +424,7 @@ class Team(GiteaApiObject): } @classmethod - def request(cls, gitea, id): + def get(cls, gitea, id): return cls._request(gitea, {"id":id}) def add(self, toAdd): @@ -501,6 +501,7 @@ class Util: time[:-3] + "00", "%Y-%m-%dT%H:%M:%S%z" ) + class Gitea: """ Has Gitea-authenticated session. Can Create Users/Organizations/Teams/... @@ -997,4 +998,6 @@ class Gitea: logging.error("Team not created... (gitea: %s)" % result["message"]) logging.error(result["message"]) raise Exception("Team not created... (gitea: %s)" % result["message"]) - return Team.parse_request(self, result) + api_object = Team.parse_request(self, result) + api_object.organization = org #fixes strange behaviour of gitea not returning a valid organization here. + return api_object diff --git a/test_api.py b/test_api.py index 3fc77e3..3ee90fe 100644 --- a/test_api.py +++ b/test_api.py @@ -32,19 +32,19 @@ def test_token_owner(): assert gitea.get_user().username == "test", "Token user not 'test'." def test_gitea_version(): - assert gitea.get_version() == "1.8.0", "Version changed. Updated?" + assert gitea.get_version() == "1.8.2", "Version changed. Updated?" def test_fail_get_non_existent_user(): with pytest.raises(NotFoundException) as e: - User.request(gitea, test_user) + User.get(gitea, test_user) def test_fail_get_non_existent_org(): with pytest.raises(NotFoundException) as e: - Organization.request(gitea, test_org) + Organization.get(gitea, test_org) def test_fail_get_non_existent_repo(): with pytest.raises(NotFoundException) as e: - Repository.request(gitea, test_user, test_repo) + Repository.get(gitea, test_user, test_repo) def test_create_user(): email = test_user + "@example.org" @@ -66,7 +66,7 @@ def test_create_org(): assert not org.full_name def test_create_repo_userowned(): - org = User.request(gitea, test_user) + org = User.get(gitea, test_user) repo = gitea.create_repo(org, test_repo, "user owned repo") assert repo.description == "user owned repo" assert repo.owner == org @@ -74,7 +74,7 @@ def test_create_repo_userowned(): assert not repo.private def test_create_repo_orgowned(): - org = Organization.request(gitea, test_org) + org = Organization.get(gitea, test_org) repo = gitea.create_repo(org, test_repo, "descr") assert repo.description == "descr" assert repo.owner == org @@ -82,41 +82,41 @@ def test_create_repo_orgowned(): assert not repo.private def test_create_team(): - org = Organization.request(gitea, test_org) + org = Organization.get(gitea, "AlreadyPresentOrg") team = gitea.create_team(org, test_team, "descr") assert team.name == test_team assert team.description == "descr" assert team.organization == org def test_delete_repo_userowned(): - org = User.request(gitea, test_user) - repo = Repository.request(gitea, org.username, test_repo) + org = User.get(gitea, test_user) + repo = Repository.get(gitea, org.username, test_repo) repo.delete() with pytest.raises(NotFoundException) as e: - Repository.request(gitea, test_user, test_repo) + Repository.get(gitea, test_user, test_repo) def test_delete_repo_orgowned(): - org = Organization.request(gitea, test_org) - repo = Repository.request(gitea, org.username, test_repo) + org = Organization.get(gitea, test_org) + repo = Repository.get(gitea, org.username, test_repo) repo.delete() with pytest.raises(NotFoundException) as e: - Repository.request(gitea, test_user, test_repo) + Repository.get(gitea, test_user, test_repo) def test_delete_team(): - org = Organization.request(gitea, test_org) - team = Team.request(org, test_team) + org = Organization.get(gitea, "AlreadyPresentOrg") + team = Team.get(org, test_team) team.delete() with pytest.raises(NotFoundException) as e: - Team(org, test_team) + Team.get(org, test_team) def test_delete_org(): - org = Organization.request(gitea, test_org) + org = Organization.get(gitea, test_org) org.delete() with pytest.raises(NotFoundException) as e: - Organization.request(gitea, test_org) + Organization.get(gitea, test_org) def test_delete_user(): - user = User.request(gitea, test_user) + user = User.get(gitea, test_user) user.delete() with pytest.raises(NotFoundException) as e: - User.request(gitea, test_user) \ No newline at end of file + User.get(gitea, test_user) \ No newline at end of file From 8a02cd7e27db617894525d1012c25300bce6fae6 Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Wed, 12 Jun 2019 00:06:55 +0200 Subject: [PATCH 7/8] added using properties instead of plain fields to track changing and access to invalid objects --- gitea/gitea.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index f51c901..fc6635a 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -12,6 +12,9 @@ class AlreadyExistsException(Exception): class NotFoundException(Exception): pass +class ObjectIsInvalid(Exception): + pass + class GiteaApiObject: @@ -20,6 +23,7 @@ class GiteaApiObject: def __init__(self, gitea, id: int): self.id = id self.gitea = gitea + self.deleted = False #set if .delete was called, so that an exception is risen def __eq__(self, other): return other.id == self.id if isinstance(other, type(self)) else False @@ -59,13 +63,23 @@ class GiteaApiObject: @classmethod def _initialize(cls, gitea, api_object, result): - for i, v in result.items(): - if i in cls.fields_to_parsers and v is not None: - parse_func = cls.fields_to_parsers[i] - setattr(api_object, i, parse_func(gitea, v)) - else: - setattr(api_object, i, v) + for name, value in result.items(): + if name in cls.fields_to_parsers and value is not None: + parse_func = cls.fields_to_parsers[name] + value = parse_func(gitea, value) + prop = property( + (lambda name: lambda self: self.__get_var(name))(name), + (lambda name: lambda self, v: self.__set_var(name, v))(name)) + setattr(cls, name, prop) + setattr(api_object, "__"+name, value) + def __set_var(self,name,i): + setattr(self,"__"+name,i) + + def __get_var(self,name): + if self.deleted: + raise ObjectIsInvalid() + return getattr(self,"__"+name) class Organization(GiteaApiObject): From 7cc91a540a658755f10d4dc9d648e2a5b7f8aaea Mon Sep 17 00:00:00 2001 From: Langenfeld Date: Wed, 12 Jun 2019 10:58:39 +0200 Subject: [PATCH 8/8] reverted name change (did not sound right); added get team by name to organizations; --- gitea/gitea.py | 30 ++++++++++++++++++++---------- test_api.py | 38 +++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/gitea/gitea.py b/gitea/gitea.py index fc6635a..39dfc59 100644 --- a/gitea/gitea.py +++ b/gitea/gitea.py @@ -23,18 +23,21 @@ class GiteaApiObject: def __init__(self, gitea, id: int): self.id = id self.gitea = gitea - self.deleted = False #set if .delete was called, so that an exception is risen + self.deleted = False # set if .delete was called, so that an exception is risen def __eq__(self, other): return other.id == self.id if isinstance(other, type(self)) else False + def __str__(self): + return "GiteaAPIObject (%s) id: %s"%(type(self),self.id) + def __hash__(self): return self.id fields_to_parsers = {} @classmethod - def get(cls, gitea, id): + def request(cls, gitea, id): """Use for ginving a nice e.g. 'request(gita, orgname, repo, ticket)'. All args are put into an args tuple for passing around""" return cls._request(gitea, {"id":id}) @@ -95,7 +98,7 @@ class Organization(GiteaApiObject): super(Organization, self).__init__(gitea, id=id) @classmethod - def get(cls, gitea, name): + def request(cls, gitea, name): return cls._request(gitea, {"name": name}) # oldstuff @@ -123,7 +126,14 @@ class Organization(GiteaApiObject): results = self.gitea.requests_get( Organization.ORG_TEAMS_REQUEST % self.username ) - return [Team.parse_request(self, result) for result in results] + return [Team.parse_request(self.gitea, result) for result in results] + + def get_team_by_name(self, name): + teams = self.get_teams() + for team in teams: + if team.name == name: + return team + raise NotFoundException() def get_members(self): """ Get all members of this Organization @@ -179,7 +189,7 @@ class User(GiteaApiObject): super(User, self).__init__(gitea, id=id) @classmethod - def get(cls, gitea, name): + def request(cls, gitea, name): return cls._request(gitea, {"name": name}) @@ -260,7 +270,7 @@ class Repository(GiteaApiObject): } @classmethod - def get(cls, gitea, owner, name): + def request(cls, gitea, owner, name): return cls._request(gitea, {"owner": owner, "name": name}) def get_branches(self): @@ -357,7 +367,7 @@ class Milestone(GiteaApiObject): } @classmethod - def get(cls, gitea, owner, repo, number): + def request(cls, gitea, owner, repo, number): return cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) def full_print(self): @@ -384,7 +394,7 @@ class Issue(GiteaApiObject): } @classmethod - def get(cls, gitea, owner, repo, number): + def request(cls, gitea, owner, repo, number): api_object = cls._request(gitea, {"owner":owner, "repo":repo, "number":number}) return api_object @@ -417,7 +427,7 @@ class Branch(GiteaApiObject): super(Branch, self).__init__(gitea, id=id) @classmethod - def get(cls, gitea, owner, repo, ref): + def request(cls, gitea, owner, repo, ref): return cls._request(gitea, {"owner":owner, "repo":repo, "ref":ref}) @@ -438,7 +448,7 @@ class Team(GiteaApiObject): } @classmethod - def get(cls, gitea, id): + def request(cls, gitea, id): return cls._request(gitea, {"id":id}) def add(self, toAdd): diff --git a/test_api.py b/test_api.py index 3ee90fe..d1eee66 100644 --- a/test_api.py +++ b/test_api.py @@ -36,15 +36,15 @@ def test_gitea_version(): def test_fail_get_non_existent_user(): with pytest.raises(NotFoundException) as e: - User.get(gitea, test_user) + User.request(gitea, test_user) def test_fail_get_non_existent_org(): with pytest.raises(NotFoundException) as e: - Organization.get(gitea, test_org) + Organization.request(gitea, test_org) def test_fail_get_non_existent_repo(): with pytest.raises(NotFoundException) as e: - Repository.get(gitea, test_user, test_repo) + Repository.request(gitea, test_user, test_repo) def test_create_user(): email = test_user + "@example.org" @@ -66,7 +66,7 @@ def test_create_org(): assert not org.full_name def test_create_repo_userowned(): - org = User.get(gitea, test_user) + org = User.request(gitea, test_user) repo = gitea.create_repo(org, test_repo, "user owned repo") assert repo.description == "user owned repo" assert repo.owner == org @@ -74,7 +74,7 @@ def test_create_repo_userowned(): assert not repo.private def test_create_repo_orgowned(): - org = Organization.get(gitea, test_org) + org = Organization.request(gitea, test_org) repo = gitea.create_repo(org, test_repo, "descr") assert repo.description == "descr" assert repo.owner == org @@ -82,41 +82,41 @@ def test_create_repo_orgowned(): assert not repo.private def test_create_team(): - org = Organization.get(gitea, "AlreadyPresentOrg") + org = Organization.request(gitea, "AlreadyPresentOrg") team = gitea.create_team(org, test_team, "descr") assert team.name == test_team assert team.description == "descr" assert team.organization == org def test_delete_repo_userowned(): - org = User.get(gitea, test_user) - repo = Repository.get(gitea, org.username, test_repo) + org = User.request(gitea, test_user) + repo = Repository.request(gitea, org.username, test_repo) repo.delete() with pytest.raises(NotFoundException) as e: - Repository.get(gitea, test_user, test_repo) + Repository.request(gitea, test_user, test_repo) def test_delete_repo_orgowned(): - org = Organization.get(gitea, test_org) - repo = Repository.get(gitea, org.username, test_repo) + org = Organization.request(gitea, test_org) + repo = Repository.request(gitea, org.username, test_repo) repo.delete() with pytest.raises(NotFoundException) as e: - Repository.get(gitea, test_user, test_repo) + Repository.request(gitea, test_user, test_repo) def test_delete_team(): - org = Organization.get(gitea, "AlreadyPresentOrg") - team = Team.get(org, test_team) + org = Organization.request(gitea, "AlreadyPresentOrg") + team = Team.request(org, test_team) team.delete() with pytest.raises(NotFoundException) as e: - Team.get(org, test_team) + Team.request(org, test_team) def test_delete_org(): - org = Organization.get(gitea, test_org) + org = Organization.request(gitea, test_org) org.delete() with pytest.raises(NotFoundException) as e: - Organization.get(gitea, test_org) + Organization.request(gitea, test_org) def test_delete_user(): - user = User.get(gitea, test_user) + user = User.request(gitea, test_user) user.delete() with pytest.raises(NotFoundException) as e: - User.get(gitea, test_user) \ No newline at end of file + User.request(gitea, test_user) \ No newline at end of file