def check_if_removed_from_bugblog(bbt: Match, b: Tag, issue: Issue) -> None: if bbt is not None: text = strings.remove_smartquotes(bbt.group(1).strip()) for row in b.find_all('tr'): data = row.find_all('td') rowtext = strings.remove_smartquotes(data[1].text.strip()) if rowtext == text: break if strip_squarebrackets(rowtext) == strip_squarebrackets(text): # Fix this print( "Issue #{id}'s bug blog text has differing autocard notation." .format(id=issue.number)) old_bbt = strings.get_body_field(issue.body, 'Bug Blog Text') body = re.sub(BBT_REGEX, 'Bug Blog Text: {0}'.format(rowtext), issue.body, flags=re.MULTILINE) new_bbt = strings.get_body_field(body, 'Bug Blog Text') issue.edit(body=body) print('Updated to `{0}`'.format(rowtext)) issue.create_comment( f'Changed bug blog text from `{old_bbt}` to `{new_bbt}`') break else: print('{id} is fixed!'.format(id=issue.number)) repo.create_comment( issue, 'This bug has been removed from the bug blog!') issue.edit(state='closed')
def _upload_issue_attachments( self, issue: Issue, attachments: List[Attachment], ) -> None: body = self._upload_attachments( issue=issue, body=issue.body, attachments=attachments, ) issue.edit(body=body, )
def find_bbt_in_issue_title(issue: Issue, known_issues: Tag) -> None: title = strip_squarebrackets(issue.title).replace(' ', '') for row in known_issues.find_all('tr'): data = row.find_all('td') row_text = strip_squarebrackets(data[1].text.strip()).replace(' ', '') if row_text == title: body = issue.body body += '\nBug Blog Text: {0}'.format(data[1].text.strip()) if body != issue.body: issue.edit(body=body) return
def close_issue( *, issue: Issue, keyword_meta: KeywordMeta, keyword: str, label_strs: Set[str] ) -> None: logging.info( f"Clossing issue: #{issue.number} with message: {keyword_meta.message}" ) issue.create_comment(keyword_meta.message) issue.edit(state="closed") if keyword_meta.remove_label_on_close: if keyword in label_strs: issue.remove_from_labels(keyword)
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 close_github_issue(repo: Repository, issue: Issue) -> None: """Close a github issue Parameters ---------- repo : Repository The repository issue : Issue The issue """ try: issue.create_comment(f"Imagery seems to work again.") issue.edit(state=ISSUE_CLOSED) except Exception as e: print(f"Failed to close issue: {e}")
def update_issue_with_comments(self, issue: Issue, issue_data: Dict, dry_run: bool) -> None: meta = issue_data["issue"] if dry_run: print(f"Would update issue {issue.number} with {meta}") return issue.edit( title=meta["title"], body=meta["body"], labels=meta["labels"], state="closed" if meta["closed"] else "open", assignees=[] if meta["assignee"] is None else [meta["assignee"]], ) self.update_issue_comments(issue, issue_data["comments"], dry_run=dry_run)
def update_issue_body(issue: Issue, cards: List[str], see_also: Optional[Match]) -> None: expected = '<!-- Images --> ' images = re.search(IMAGES_REGEX, issue.body, re.MULTILINE) for row in strings.grouper(4, cards): expected = expected + '<img src="https://pennydreadfulmagic.com/image/{0}/" height="300px">'.format('|'.join([urllib.parse.quote(c) for c in row if c is not None])) if see_also is not None: for row in strings.grouper(5, re.findall(REGEX_CARDREF, see_also.group(1))): expected = expected + '<img src="https://pennydreadfulmagic.com/image/{0}/" height="250px">'.format('|'.join([urllib.parse.quote(c) for c in row if c is not None])) if not images: print('Adding Images...') body = issue.body + '\n' + expected issue.edit(body=body) elif images.group(0) != expected: print('Updating images...') body = issue.body.replace(images.group(0), expected) issue.edit(body=body)
def fix_user_errors(issue: Issue) -> None: body = issue.body # People sometimes put the affected cards on the following line. Account for that. body = re.sub(BAD_AFFECTS_REGEX, 'Affects: [', body) # People sometimes neglect Affects all-together, and only put cards in the title. affects = re.search(AFFECTS_REGEX, body, re.MULTILINE) if affects is None: cards = re.findall(REGEX_CARDREF, issue.title) cards = [c for c in cards] body = body + '\nAffects: ' + ''.join(['[' + c + ']' for c in cards]) if re.search(strings.REGEX_SEARCHREF, body): def do_search(m): search = m.group(1) n, cards, warnings = fetcher.search_scryfall(search) if n == 0 or warnings: return m.group(0) return ', '.join([f'[{c}]' for c in cards]) body = re.sub(strings.REGEX_SEARCHREF, do_search, body) # We had a bug where the above triggered infinitely. Clean it up. extra_affects = re.findall(AFFECTS_REGEX, body, re.MULTILINE) if len(extra_affects) > 1: lines = body.split('\n') if re.match(AFFECTS_REGEX, lines[-1]): body = '\n'.join(lines[:-1]) # People are missing the bullet points, and putting info on the following line instead. body = re.sub(r' - \r?\n', '', body) # Some people ignore the request for screenshots. body = body.replace('(Attach a screenshot or video here)', 'Currently Unconfirmed.') if repo.is_issue_from_bug_blog(issue): bbt = re.search(strings.BBT_REGEX, issue.body, re.MULTILINE) if not get_affects(issue) and bbt: cards = strings.get_cards_from_string(bbt.group(0)) if cards: cardlist = ', '.join([f'[{c}]' for c in cards]) body = strings.set_body_field(body, 'Affects', cardlist) # Push changes. if body != issue.body: issue.edit(body=body) # People are putting [cardnames] in square quotes, despite the fact we prefer Affects: now. title = strings.strip_squarebrackets(issue.title) if title != issue.title: print('Changing title of #{0} to "{1}"'.format(issue.number, title)) issue.edit(title=title)
def close_issue(*, issue: Issue, keyword_meta: KeywordMeta) -> None: logging.info( f"Clossing issue: #{issue.number} with message: {keyword_meta.message}" ) issue.create_comment(keyword_meta.message) issue.edit(state="closed")
def process_issue(issue: Issue) -> None: age = (datetime.datetime.now() - issue.updated_at).days if age < 5: fix_user_errors(issue) apply_screenshot_labels(issue) labels = [c.name for c in issue.labels] see_also = strings.get_body_field(issue.body, 'See Also') cards = get_affects(issue) if age < 5: check_for_invalid_card_names(issue, cards) update_issue_body(issue, cards, see_also) pd_legal = ([True for c in cards if c in pd_legal_cards()] or [False])[0] if pd_legal and not 'Affects PD' in labels: issue.add_to_labels('Affects PD') elif not pd_legal and 'Affects PD' in labels: issue.remove_from_labels('Affects PD') msg = issue.title categories = [c for c in labels if c in CATEGORIES] if not categories: if 'From Bug Blog' in labels: cat = 'Unclassified' else: cat = 'Unconfirmed' if not issue.comments: print( 'Issue #{id} was reported {days} ago, and has had no followup.' .format(id=issue.number, days=age)) if age > 30: issue.create_comment('Closing due to lack of followup.') issue.edit(state='closed') return if not 'Unclassified' in labels: issue.add_to_labels('Unclassified') elif 'Unclassified' in labels: print('Removing Unclassified from Issue #{id}'.format(id=issue.number)) issue.remove_from_labels('Unclassified') cat = categories.pop() else: cat = categories.pop() for card in cards: bannable = cat in BADCATS and 'Multiplayer' not in labels bug = { 'card': card, 'description': msg, 'category': cat, 'last_updated': str(issue.updated_at), 'pd_legal': card in pd_legal_cards(), 'bug_blog': 'From Bug Blog' in labels, 'breaking': cat in BADCATS, 'bannable': bannable, 'url': issue.html_url, } if 'Multiplayer' in labels: bug['multiplayer_only'] = True if 'Collection' in labels: bug['cade_bug'] = True if 'Deck Building' in labels: bug['cade_bug'] = True age = datetime.datetime.now() - issue.updated_at if 'Help Wanted' in labels: bug['help_wanted'] = True elif age.days > 60: bug['help_wanted'] = True bug['last_verified'] = VERIFICATION_BY_ISSUE.get(issue.number, None) ALL_BUGS.append(bug)