def update_issue_comments(self, issue: Issue, comments_data: List[Dict], dry_run: bool) -> None: issue_id = issue.number if dry_run: print(f"Would update issue {issue_id} comments") return num_comments = len(comments_data) existing_comments = list(issue.get_comments()) # Create or update comments for comment_num, comment_data in enumerate(comments_data): print( f"Set comment {comment_num + 1}/{num_comments} of github issue #{issue_id}..." ) comment_body = comment_data["body"] if comment_num < len(existing_comments): existing_comments[comment_num].edit(comment_body) else: issue.create_comment(comment_body) # Delete comments in excess comments_to_delete = existing_comments[num_comments:] for i, gcomment in enumerate(comments_to_delete): print( f"Delete extra GitHub comment {i + 1}/{len(comments_to_delete)} of issue #{issue_id}..." ) gcomment.delete()
def get_issue_comments(self, task: Task, issue: Issue) -> bool: """ Gets the issues information. Args: task (Task): The task that requires the issues data. is_outdated (Callable): A function which checks if the task gets outdated during the download process. Returns: Optional[List[dict]]: List of dictionaries, each one with the data associated with a comment. """ comments = issue.get_comments() iter_comments: Iterator = iter(comments) while True: try: comment: GistComment = next(iter_comments) self.__db_manager.create_comment( task.repo_dir, issue.id, comment.id, comment.user.login, self.__downloaded_data_cleaner(comment.body or "") ) except StopIteration: return True except RateLimitExceededException: sleep_time: float = (self.__gh_conn.get_rate_limit_reset() - datetime.utcnow() + timedelta(0, 20)).total_seconds() time.sleep(sleep_time) continue
def get_last_comment(issue: Issue) -> Optional[IssueComment]: last_comment: Optional[IssueComment] = None comment: IssueComment for comment in issue.get_comments(): if not last_comment: last_comment = comment elif comment.created_at > last_comment.created_at: last_comment = comment return last_comment
def judge_status(self, issue: Issue) -> str: bot_advice = super().judge_status(issue) # Prompt to add `issue-addressed` tag if customer has not replied > 7 days issue_labels = [label.name for label in issue.labels] if not bot_advice and 'issue-addressed' not in issue_labels and 'needs-author-feedback' not in issue_labels: if (datetime.today() - list(issue.get_comments())[-1].updated_at).days > 7: return 'no reply > 7' return bot_advice
def _already_commented(issue: Issue, *, repo: str) -> bool: """Check whether this repository has already commented on the issue.""" target = f"Repo: {repo}" if target in issue.body: return True for comment in issue.get_comments(): if target in comment.body: return True return False
def _extract_comments( self, github_issue: Issue, exclude_comments: Optional[List[str]] = None, ) -> List[TrackerIssueComment]: return [ self._extract_comment(github_comment=github_comment, ) for github_comment in github_issue.get_comments() if exclude_comments is None or str(github_comment.id) not in exclude_comments ]
def find_bbt_in_body_or_comments(issue: Issue) -> Optional[str]: body = issue.body bbt = re.search(BBT_REGEX, issue.body, re.MULTILINE) if not bbt: for comment in issue.get_comments(): if bbt is None: bbt = re.search(BBT_REGEX, comment.body, re.MULTILINE) if bbt is not None: body += '\nBug Blog Text: {0}'.format( bbt.groups()[0].strip()) if body != issue.body: issue.edit(body=body) if bbt is not None: return bbt.groups()[0].strip() return None
def _get_status_comment(github_user: AuthenticatedUser, proposal: Issue) -> Optional[IssueComment]: """Retrieves an existing status comment for a proposal Returns: The status comment, or None if it cannot be found. """ # Retrieve all of the comments for the proposal comments: PaginatedList = proposal.get_comments() # Find the latest status comment for comment in comments.reversed: if (comment.body.startswith("Team member @") and comment.user.login == github_user.login): return comment return None
def store(self, issue: GithubIssue): """Override :func:`~Entity.store`.""" if issue.number in self.previous_knowledge.index: return # if in previous knowledge, no need to analyse if issue.pull_request is not None: return # we analyze issues and prs differentely self.stored_entities[str(issue.number)] = { "title": issue.title, "body": issue.body, "created_by": issue.user.login, "created_at": int(issue.created_at.timestamp()), "closed_by": issue.closed_by.login if issue.closed_by is not None else None, "closed_at": int(issue.closed_at.timestamp()) if issue.closed_at is not None else None, "labels": GitHubKnowledge.get_labels(issue), "interactions": GitHubKnowledge.get_interactions(issue.get_comments()), }
def get_comments_last_time(issue: Issue): comments = list(issue.get_comments()) if not comments: return None return max(i.updated_at for i in comments)
def get_bot_comment(issue: Issue, bot_name: str, ps_number: str) -> IssueComment: for i in issue.get_comments(): if i.user.login == bot_name and str(ps_number) in i.body: return i
def get_users_who_commented(issue: Issue) -> Set[str]: users: Set[str] = set() for comment in issue.get_comments(): users.add("@" + comment.user.login) return users
def judge_status(self, issue: Issue) -> str: if issue.user.login in self.language_owner: return '' latest_comments = '' comments = [(comment.updated_at.timestamp(), comment.user.login) for comment in issue.get_comments() if comment.user.login not in self.bot_assignees] comments.sort() if comments: latest_comments = comments[-1][1] if issue.comments == 0: return 'new issue' elif latest_comments not in self.language_owner: return 'new comment' else: return ''
def get_first_bot_response(issue: Issue) -> typing.Optional[int]: """Get timestamps for all bot comments in issue.""" for comment in issue.get_comments(): if comment.user.login in BOTS: return int(comment.created_at.timestamp()) return None