Example #1
0
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)
Example #2
0
def check_for_invalid_card_names(issue: Issue, cards: List[str]) -> None:
    labels = [lab.name for lab in issue.labels]
    fail = False
    for c in cards:
        if '//' in c:
            pass
        elif not c in cardnames():
            fail = True
    if fail and not 'Invalid Card Name' in labels:
        issue.add_to_labels('Invalid Card Name')
    elif not fail and 'Invalid Card Name' in labels:
        issue.remove_from_labels('Invalid Card Name')
Example #3
0
def process_issue(*, issue: Issue, settings: Settings) -> None:
    logging.info(f"Processing issue: #{issue.number}")
    label_strs = set([label.name for label in issue.get_labels()])
    events = list(issue.get_events())
    labeled_events = get_labeled_events(events)
    last_comment = get_last_comment(issue)
    for keyword, keyword_meta in settings.input_config.items():
        # Check closable delay, if enough time passed and the issue could be closed
        closable_delay = (
            last_comment is None
            or (datetime.utcnow() - keyword_meta.delay) > last_comment.created_at
        )
        # Check label, optionally removing it if there's a comment after adding it
        if keyword in label_strs:
            logging.info(f'Keyword: "{keyword}" in issue labels')
            keyword_event = get_last_event_for_label(
                labeled_events=labeled_events, label=keyword
            )
            if (
                last_comment
                and keyword_event
                and last_comment.created_at > keyword_event.created_at
            ):
                logging.info(
                    f"Not closing as the last comment was written after adding the "
                    f'label: "{keyword}"'
                )
                if keyword_meta.remove_label_on_comment:
                    logging.info(f'Removing label: "{keyword}"')
                    issue.remove_from_labels(keyword)
            elif closable_delay:
                close_issue(
                    issue=issue,
                    keyword_meta=keyword_meta,
                    keyword=keyword,
                    label_strs=label_strs,
                )
                break
            else:
                logging.info(
                    f"Not clossing issue: #{issue.number} as the delay hasn't been reached: {keyword_meta.delay}"
                )
Example #4
0
def apply_screenshot_labels(issue: Issue) -> None:
    labels = [c.name for c in issue.labels]
    has_screenshot = 'Has Screenshot' in labels
    has_video = 'Has Video' in labels

    if '(https://user-images.githubusercontent.com/' in issue.body:
        has_screenshot = True
    if 'https://imgur.com/' in issue.body:
        has_screenshot = True
    if 'https://i.imgur.com' in issue.body:
        has_screenshot = True
    if 'https://youtu.be/' in issue.body:
        has_video = True
    if 'youtube.com/watch' in issue.body:
        has_video = True
    if 'clips.twitch.tv/' in issue.body:
        has_video = True

    if has_screenshot and not 'Has Screenshot' in labels:
        issue.add_to_labels('Has Screenshot')
    if has_screenshot and 'Needs Screenshot' in labels:
        issue.remove_from_labels('Needs Screenshot')

    if has_video and not 'Has Video' in labels:
        issue.add_to_labels('Has Video')
    if has_video and 'Needs Video' in labels:
        issue.remove_from_labels('Needs Video')
    if has_video and 'Needs Screenshot' in labels:
        issue.remove_from_labels('Needs Screenshot')

    if not has_screenshot and not has_video and not 'Needs Screenshot' in labels:
        issue.add_to_labels('Needs Screenshot')
    if has_screenshot and not has_video and not 'Needs Video' in labels:
        issue.add_to_labels('Needs Video')
Example #5
0
def process_issue(*, issue: Issue, settings: Settings,
                  owner: NamedUser) -> None:
    logging.info(f"Processing issue: #{issue.number}")
    label_strs = set([l.name for l in issue.get_labels()])
    events = list(issue.get_events())
    labeled_events = get_labeled_events(events)
    last_comment = get_last_comment(issue)
    for keyword, keyword_meta in settings.input_config.items():
        # Check closable delay, if enough time passed and the issue could be closed
        closable_delay = False
        if (last_comment is None or (datetime.utcnow() - keyword_meta.delay) >
                last_comment.created_at):
            closable_delay = True
        # Check label, optionally removing it if there's a comment after adding it
        if keyword in label_strs:
            logging.info(f'Keyword: "{keyword}" in issue labels')
            keyword_event = get_last_event_for_label(
                labeled_events=labeled_events, label=keyword)
            if last_comment and last_comment.created_at > keyword_event.created_at:
                logging.info(
                    f"Not closing as the last comment was written after adding the "
                    f'label: "{keyword}"')
                if keyword_meta.remove_label:
                    logging.info(f'Removing label: "{keyword}"')
                    issue.remove_from_labels(keyword)
            elif closable_delay:
                close_issue(issue=issue, keyword_meta=keyword_meta)
                break
        # Check HTML comments by allowed users
        if (last_comment
                and f"<!-- issue-manager: {keyword} -->" in last_comment.body
                and closable_delay and last_comment.user.login
                in keyword_meta.users + [owner.login]):
            logging.info(
                f'Last comment by user: "******" had HTML keyword '
                f'comment: "{keyword}" and there\'s a closable delay.')
            close_issue(issue=issue, keyword_meta=keyword_meta)
            break
Example #6
0
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)