From af590206ab0775459884f127644198a2e019a976 Mon Sep 17 00:00:00 2001 From: Valerio Cosentino Date: Fri, 28 Dec 2018 15:08:29 +0100 Subject: [PATCH] [gitlab] Add organization info This code enhances the backend to fetch user data, which includes his organization. --- perceval/backends/core/gitlab.py | 62 ++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/perceval/backends/core/gitlab.py b/perceval/backends/core/gitlab.py index 3b55e4711..0b6f370c8 100644 --- a/perceval/backends/core/gitlab.py +++ b/perceval/backends/core/gitlab.py @@ -81,7 +81,7 @@ class GitLab(Backend): :param sleep_time: time to sleep in case :param blacklist_ids: ids of items that must not be retrieved """ - version = '0.6.2' + version = '0.7.0' CATEGORIES = [CATEGORY_ISSUE, CATEGORY_MERGE_REQUEST] @@ -221,6 +221,9 @@ def __fetch_issues(self, from_date): self.__init_issue_extra_fields(issue) + issue['author_data'] = self.__get_user(issue['author']) + issue['assignee_data'] = self.__get_user(issue['assignee']) + issue['assignees_data'] = self.__get_issue_assignees(issue['assignees']) issue['notes_data'] = \ self.__get_issue_notes(issue_id) issue['award_emoji_data'] = \ @@ -228,6 +231,15 @@ def __fetch_issues(self, from_date): yield issue + def __get_issue_assignees(self, raw_assignees): + """Get issue assignees""" + + assignees = [] + for ra in raw_assignees: + assignees.append(self.__get_user(ra)) + + return assignees + def __get_issue_notes(self, issue_id): """Get issue notes""" @@ -239,6 +251,7 @@ def __get_issue_notes(self, issue_id): for note in json.loads(raw_notes): note_id = note['id'] + note['author_data'] = self.__get_user(note['author']) note['award_emoji_data'] = \ self.__get_note_award_emoji(GitLabClient.ISSUES, issue_id, note_id) notes.append(note) @@ -267,6 +280,9 @@ def __fetch_merge_requests(self, from_date): self.__init_merge_extra_fields(merge_full) + merge_full['author_data'] = self.__get_user(merge_full['author']) + merge_full['assignee_data'] = self.__get_user(merge_full['assignee']) + merge_full['notes_data'] = self.__get_merge_notes(merge_id) merge_full['award_emoji_data'] = self.__get_award_emoji(GitLabClient.MERGES, merge_id) merge_full['versions_data'] = self.__get_merge_versions(merge_id) @@ -283,6 +299,7 @@ def __get_merge_notes(self, merge_id): for raw_notes in group_notes: for note in json.loads(raw_notes): note_id = note['id'] + note['author_data'] = self.__get_user(note['author']) note['award_emoji_data'] = \ self.__get_note_award_emoji(GitLabClient.MERGES, merge_id, note_id) notes.append(note) @@ -333,22 +350,45 @@ def __get_note_award_emoji(self, item_type, item_id, note_id): emojis.append(emoji) except requests.exceptions.HTTPError as error: if error.response.status_code == 404: - logger.warning("Emojis not available for %s ", + logger.warning("Emojis not available for %s", urijoin(item_type, str(item_id), GitLabClient.NOTES, str(note_id), GitLabClient.EMOJI)) return emojis return emojis + def __get_user(self, user): + """Fetch user data""" + + found = {} + + if not user: + return found + + if 'id' not in user: + logger.warning("User %s has no ID", user) + return found + + user_raw = self.client.user(user['id']) + found = json.loads(user_raw) + + return found + def __init_issue_extra_fields(self, issue): """Add fields to an issue""" + issue['author_data'] = {} + issue['assignee_data'] = {} + issue['assignees_data'] = [] + issue['notes_data'] = [] issue['notes_data'] = [] issue['award_emoji_data'] = [] def __init_merge_extra_fields(self, merge): """Add fields to a merge requests""" + merge['author_data'] = {} + merge['assignee_data'] = {} merge['notes_data'] = [] merge['award_emoji_data'] = [] merge['versions_data'] = [] @@ -384,7 +424,7 @@ class GitLabClient(HttpClient, RateLimitHandler): PROJECTS = "projects" VERSIONS = "versions" - _users = {} # users cache + _users = {} # users cache def __init__(self, owner, repository, token, base_url=None, sleep_for_rate=False, min_rate_to_sleep=MIN_RATE_LIMIT, @@ -517,6 +557,22 @@ def note_emojis(self, item_type, item_id, note_id): return self.fetch_items(path, payload) + def user(self, user_id): + """Get the user information and update the user cache""" + + if user_id in self._users: + return self._users[user_id] + + url_user = urijoin(self.base_url, 'users', user_id) + + logging.info("Getting info for %s" % url_user) + + r = self.fetch(url_user) + user = r.text + self._users[user_id] = user + + return user + def calculate_time_to_reset(self): """Calculate the seconds to reset the token requests, by obtaining the different between the current date and the next date when the token is fully regenerated.