def test_get_issue_comments(self): """Test the github utility get_issue_comments method.""" params = { 'sort': 'created', 'direction': 'desc', } params = urlencode(params, quote_via=quote_plus) owner = 'gitcoinco' repo = 'web' url = f'https://api.github.com/repos/{owner}/{repo}/issues/comments?' + params responses.add(responses.GET, url, headers=HEADERS, json={}, status=200) get_issue_comments(owner, repo) assert responses.calls[0].request.url == url
def fetch_issue_comments(self, save=True): """Fetch issue comments for the associated Github issue. Args: save (bool): Whether or not to save the Bounty after fetching. Returns: dict: The comments data dictionary provided by Github. """ if self.github_url.lower()[:19] != 'https://github.com/': return [] parsed_url = urlsplit(self.github_url) try: github_user, github_repo, _, github_issue = parsed_url.path.split( '/')[1:5] except ValueError: logger.info('Invalid github url for Bounty: %s -- %s', self.pk, self.github_url) return [] comments = get_issue_comments(github_user, github_repo, github_issue) if isinstance(comments, dict) and comments.get('message') == 'Not Found': logger.info('Bounty %s contains an invalid github url %s', self.pk, self.github_url) return [] comment_count = 0 for comment in comments: if comment['user']['login'] not in settings.IGNORE_COMMENTS_FROM: comment_count += 1 self.github_comments = comment_count if save: self.save() return comments
def fetch_issue_comments(self, save=True): if self.github_url.lower()[:19] != 'https://github.com/': return [] parsed_url = urlsplit(self.github_url) try: github_user, github_repo, _, github_issue = parsed_url.path.split( '/')[1:5] except ValueError: logger.info('Invalid github url for Bounty: %s -- %s', self.pk, self.github_url) return [] comments = get_issue_comments(github_user, github_repo, github_issue) if isinstance(comments, dict) and comments.get('message') == 'Not Found': logger.info('Bounty %s contains an invalid github url %s', self.pk, self.github_url) return [] comment_count = 0 for comment in comments: if comment['user']['login'] not in settings.IGNORE_COMMENTS_FROM: comment_count += 1 self.github_comments = comment_count if save: self.save() return comments
def handle(self, *args, **options): notifications = get_notifications() print(len(notifications)) for notification in notifications: process_me = notification['reason'] == 'mention' if process_me: try: url = notification['subject']['url'] url = url.replace('/repos', '') url = url.replace('//api.github', '//github') latest_comment_url = notification['subject']['latest_comment_url'] _org_name = org_name(url) _repo_name = repo_name(url) _issue_number = issue_number(url) _comment_id = latest_comment_url.split('/')[-1] comment = get_issue_comments(_org_name, _repo_name, _issue_number, _comment_id) does_mention_gitcoinbot = settings.GITHUB_API_USER in comment.get('body','') if comment.get('message','') == "Not Found": print("comment was not found") elif not does_mention_gitcoinbot: print("does not mention gitcoinbot") else: comment_from = comment['user']['login'] num_reactions = comment['reactions']['total_count'] print(_org_name, _repo_name, _issue_number, _comment_id, num_reactions, comment_from) is_from_gitcoinbot = settings.GITHUB_API_USER in comment_from if num_reactions == 0 and not is_from_gitcoinbot: print("unprocessed") post_issue_comment_reaction(_org_name, _repo_name, _comment_id, 'heart') comment = f"@{comment_from}. :wave: thanks for the atMention, but you need to [install @gitcoinbot on this repo for me to be able to respond](https://github.com/apps/gitcoinbot). More details [in the documentation](https://github.com/gitcoinco/web/tree/master/app/gitcoinbot).\n\n:v:\n@gitcoinbot" post_issue_comment(_org_name, _repo_name, _issue_number, comment) except Exception as e: logging.exception(e) print(e)
def handle(self, *args, **options): num_days_back_to_warn = 3 num_days_back_to_delete_interest = 7 days = [i * 3 for i in range(1, 15)] if settings.DEBUG: days = range(1, 1000) for day in days: interests = Interest.objects.filter( created__gte=(timezone.now() - timezone.timedelta(days=(day+1))), created__lt=(timezone.now() - timezone.timedelta(days=day)), ).all() print('day {} got {} interests'.format(day, interests.count())) for interest in interests: for bounty in Bounty.objects.filter(interested=interest, current_bounty=True, idx_status__in=['open', 'started', 'submitted']): print("{} is interested in {}".format(interest, bounty)) try: owner = org_name(bounty.github_url) repo = repo_name(bounty.github_url) issue_num = issue_number(bounty.github_url) comments = get_issue_comments(owner, repo, issue_num) comments_by_interested_party = [comment for comment in comments if comment['user']['login'] == interest.profile.handle] should_warn_user = False should_delete_interest = False last_heard_from_user_days = None if len(comments_by_interested_party) == 0: should_warn_user = True should_delete_interest = False else: # example format: 2018-01-26T17:56:31Z' time_format = '%Y-%m-%dT%H:%M:%SZ' last_comment_by_user = datetime.strptime(comments_by_interested_party[0]['created_at'], time_format) delta_now_vs_last_comment = datetime.now() - last_comment_by_user last_heard_from_user_days = delta_now_vs_last_comment.days should_warn_user = last_heard_from_user_days >= num_days_back_to_warn should_delete_interest = last_heard_from_user_days >= num_days_back_to_delete_interest if should_delete_interest: print('executing should_delete_interest for {}'.format(interest.pk)) bounty_startwork_expired(interest.profile.email, bounty, interest, last_heard_from_user_days) interest.delete() elif should_warn_user: print('executing should_warn_user for {}'.format(interest.pk)) bounty_startwork_expire_warning(interest.profile.email, bounty, interest, last_heard_from_user_days) except Exception as e: print(e)
def fetch_issue_comments(self, save=True): """Fetch issue comments for the associated Github issue. Args: save (bool): Whether or not to save the Bounty after fetching. Returns: dict: The comments data dictionary provided by Github. """ if self.github_url.lower()[:19] != 'https://github.com/': return [] parsed_url = urlsplit(self.github_url) try: github_user, github_repo, _, github_issue = parsed_url.path.split( '/')[1:5] except ValueError: logger.info( f'Invalid github url for Bounty: {self.pk} -- {self.github_url}' ) return [] comments = get_issue_comments(github_user, github_repo, github_issue) if isinstance(comments, dict) and comments.get('message', '') == 'Not Found': logger.info( f'Bounty {self.pk} contains an invalid github url {self.github_url}' ) return [] comment_count = 0 for comment in comments: if (isinstance(comment, dict) and comment.get('user', {}).get( 'login', '') not in settings.IGNORE_COMMENTS_FROM): comment_count += 1 self.github_comments = comment_count if comment_count: comment_times = [ datetime.strptime(comment['created_at'], '%Y-%m-%dT%H:%M:%SZ') for comment in comments ] max_comment_time = max(comment_times) max_comment_time = max_comment_time.replace(tzinfo=pytz.utc) self.last_comment_date = max_comment_time if save: self.save() return comments
def handle(self, *args, **options): notifications = get_notifications() print(len(notifications)) for notification in notifications: process_me = notification['reason'] == 'mention' if process_me: try: url = notification['subject']['url'] url = url.replace('/repos', '') url = url.replace('//api.github', '//github') latest_comment_url = notification['subject'][ 'latest_comment_url'] _org_name = org_name(url) _repo_name = repo_name(url) _issue_number = issue_number(url) _comment_id = latest_comment_url.split('/')[-1] comment = get_issue_comments(_org_name, _repo_name, _issue_number, _comment_id) does_mention_gitcoinbot = settings.GITHUB_API_USER in comment.get( 'body', '') if comment.get('message', '') == "Not Found": print("comment was not found") elif not does_mention_gitcoinbot: print("does not mention gitcoinbot") else: comment_from = comment['user']['login'] num_reactions = comment['reactions']['total_count'] print(_org_name, _repo_name, _issue_number, _comment_id, num_reactions, comment_from) is_from_gitcoinbot = settings.GITHUB_API_USER in comment_from if num_reactions == 0 and not is_from_gitcoinbot: print("unprocessed") post_issue_comment_reaction( _org_name, _repo_name, _comment_id, 'heart') except Exception as e: logging.exception(e) print(e)
def handle(self, *args, **options): num_days_back_to_warn = 3 num_days_back_to_delete_interest = 7 days = [i * 3 for i in range(1, 15)] if settings.DEBUG: days = range(1, 1000) for day in days: interests = Interest.objects.filter( created__gte=(timezone.now() - timezone.timedelta(days=(day + 1))), created__lt=(timezone.now() - timezone.timedelta(days=day)), ).all() print('day {} got {} interests'.format(day, interests.count())) for interest in interests: for bounty in Bounty.objects.filter( interested=interest, current_bounty=True, idx_status__in=['open', 'started']): print("{} is interested in {}".format(interest, bounty)) try: owner = org_name(bounty.github_url) repo = repo_name(bounty.github_url) issue_num = issue_number(bounty.github_url) comments = get_issue_comments(owner, repo, issue_num) comments_by_interested_party = [ comment for comment in comments if comment['user'] ['login'] == interest.profile.handle ] should_warn_user = False should_delete_interest = False last_heard_from_user_days = None if len(comments_by_interested_party) == 0: should_warn_user = True should_delete_interest = False else: # example format: 2018-01-26T17:56:31Z' comment_times = [ datetime.strptime(comment['created_at'], '%Y-%m-%dT%H:%M:%SZ') for comment in comments_by_interested_party ] last_comment_by_user = max(comment_times) # if user hasn't commented since they expressed interest, handled this condition # per https://github.com/gitcoinco/web/issues/462#issuecomment-368384384 if last_comment_by_user < interest.created_at.replace( tzinfo=None): last_comment_by_user = interest.created_at.replace( tzinfo=None) # some small calcs delta_now_vs_last_comment = datetime.now( ) - last_comment_by_user last_heard_from_user_days = delta_now_vs_last_comment.days # decide action params should_warn_user = last_heard_from_user_days >= num_days_back_to_warn should_delete_interest = last_heard_from_user_days >= num_days_back_to_delete_interest print( f"- its been {last_heard_from_user_days} days since we heard from the user" ) if should_delete_interest: print('executing should_delete_interest for {}'. format(interest.pk)) bounty_startwork_expired( interest.profile.email, bounty, interest, last_heard_from_user_days) interest.delete() elif should_warn_user: print('executing should_warn_user for {}'.format( interest.pk)) bounty_startwork_expire_warning( interest.profile.email, bounty, interest, last_heard_from_user_days) except Exception as e: print(e)