From 288f94ae28e340024c12e2efbe9ce95bc67bf55a Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Fri, 13 Sep 2019 18:34:40 -0500 Subject: [PATCH] Expand interface and changed storage of backing object for Project. Testing revealed that if a gitlab.project object was passed to Project's constructor, it wouldn't store all of the attributes. This might be unique to how the test obtained the gitlab.project object; even if so, we need to protect against it. --- gitlab_classes.py | 84 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/gitlab_classes.py b/gitlab_classes.py index 87328fd..2be43b1 100644 --- a/gitlab_classes.py +++ b/gitlab_classes.py @@ -1,12 +1,9 @@ from datetime import datetime +from datetime import timezone import gitlab from config import Config -def gitlab_timestamp_to_datetime(timestamp): - return datetime.fromisoformat(timestamp) - - class Session: __instance = None @@ -44,6 +41,10 @@ class User: def get_site(self): return self.git_user.web_url + def __repr__(self): + username = self.get_username() + return f'@{username}' + class Issue: def __init__(self, issue): @@ -66,6 +67,18 @@ class Issue: """ return self.git_issue.iid + def get_title(self): + """ + :return: issue's title + """ + return self.git_issue.title + + def get_description(self): + """ + :return: issue's description + """ + return self.git_issue.description + def get_state(self): """ :return: opened or closed @@ -115,6 +128,11 @@ class Issue: """ return self.git_issue.web_url + def __repr__(self): + issue_number = self.get_project_issue_id() + title = self.get_title() + return f'{issue_number}. {title}' + # other git_issue fields: # project_id # title @@ -154,11 +172,19 @@ class Project: elif isinstance(project, str): # by path self.git_project = Session.get_session().projects.get(project) else: - self.git_project = project + # self.git_project = project # for some reason, many attributes (including members) might be lost + self.git_project = Session.get_session().projects.get(project.id) @staticmethod - def get_projects_by_group(group_id): - gitlab_projects = Session.get_session().groups.get(group_id).projects.list(all=True) + def get_projects_by_group(group): + """ + :param group: must be either an integer representing the group ID, or a string containing the group's namespace + :return: list of projects in the specified group + """ + if isinstance(group, int): # by group id + gitlab_projects = Session.get_session().groups.get(group).projects.list(all=True) + else: # isinstance(group, str): # by path + gitlab_projects = Session.get_session().groups.get(group).projects.list(all=True) projects = [] for project in gitlab_projects: projects.append(Project(project)) @@ -238,6 +264,15 @@ class Project: """ return User(self.git_project.creator_id) + def get_created_at(self): + """ + :return: an "aware" datetime object representing the creation date/time + """ + created_at = self.git_project.created_at + if created_at[-1] in ('z', 'Z'): + created_at = created_at[:-1] + '+00:00' + return datetime.fromisoformat(created_at) + def get_users(self): """ :return: List of User objects representing the project's members (not including inherited members) @@ -275,9 +310,11 @@ class Project: gitlab_issue = self.git_project.issues.create({'title': title, 'description': description}) return Issue(gitlab_issue) + def __repr__(self): + return self.get_name_with_namespace() + # other git_project fields: # description - # created_at # default_branch # tag_list # http_url_to_repo https URL to clone repository @@ -323,3 +360,34 @@ class Project: # auto_devops_enabled # auto_devops_deploy_strategy # permissions + + +if __name__ == '__main__': + namespace = 'csce_361/sandbox' + test_projects = Project.get_projects_by_group(namespace) + print('All projects in sandbox:') + for test_project in test_projects: + print(test_project) + print('Selecting second project. Here are the members:') + test_project = test_projects[1] + members = test_project.get_users() + for member in members: + print(member) + print('Here are ALL the members:') + members = test_project.get_all_users() + for member in members: + print(member) + print('Here are the issues:') + test_issues = test_project.get_issues() + for test_issue in test_issues: + creation = test_issue.get_created_at() + print(f'{test_issue}\tcreated at {creation}.') + test_projects = Project.get_projects_by_keyword('csce361-homework') + number_of_projects = len(test_projects) + print(f'retrieved {number_of_projects} projects matching \'csce361-homework\'') + start_date = datetime(2019, 8, 1, tzinfo=timezone.utc) + test_projects = list(filter(lambda p: p.get_created_at() > start_date, test_projects)) + new_number_of_projects = len(test_projects) + print(f'after culling, there are {new_number_of_projects} projects that were created in/after August 2019') + print(f'including {test_projects[0]} created by {test_projects[0].get_creator()} at ' + f'{test_projects[0].get_created_at()}.') -- GitLab