示例#1
0
def label_issue_slack(event_data):
    label_text = event_data.get('text', '')
    channel_id = event_data.get('channel_id', '')
    uid = event_data.get('user_id', '')
    response = is_maintainer_comment(uid)
    tokens = label_text.split(' ')
    label_list_tokens = label_text.split('[')
    if response.get('is_maintainer', False):
        if len(tokens) < 3 and len(
                label_list_tokens) != 2 and "]" not in label_text:
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('error_view_command', ''))
            return {'message': 'Wrong format'}
        else:
            label_list_tokens = '@sys-bot label %s' % label_list_tokens[
                1].split(']')[0]
            response = label_list_issue(org_repo_owner, tokens[0], tokens[1],
                                        label_list_tokens)
            if response.get('status', 400) == 400:
                send_message_ephemeral(
                    channel_id, uid, MESSAGE.get('incorrect_info_provided',
                                                 ''))
                return {'message': 'Wrong info'}
            else:
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('success', ''))
                return {'message': 'Labelled issue'}
    else:
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('not_a_maintainer', ''))
        return {'message': "Not a maintainer"}
示例#2
0
def open_issue_slack(data):  # pragma: no cover
    channel_id = data.get('channel_id', '')
    uid = data.get('user_id', '')
    # Get the command parameters used by the user
    command_params = data.get('text', '')
    # For getting author name and repo name
    tokens = command_params.split(' ')
    # For extracting title, description, update list item, and estimation
    title_body_tokens = command_params.split('*')
    if command_params == "" or len(tokens) < 6 or len(title_body_tokens) < 5 or \
            title_body_tokens[1] == '' or title_body_tokens[2] == '' or \
            title_body_tokens[3] == '' or title_body_tokens[4] == '':
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('wrong_params_issue_command', ''))
        return {"message": "Wrong parameters for command"}
    # Each part is extracted and will be put into the template
    issue_title = title_body_tokens[1]
    issue_description = title_body_tokens[2]
    update_list_item = title_body_tokens[3]
    estimation = title_body_tokens[4]
    status = open_issue_github(org_repo_owner, tokens[0], issue_title,
                               issue_description, update_list_item, estimation,
                               tokens[1])
    if status == 201:
        # If issue has been opened successfully
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('success_issue', ''))
        return {"message": "Successfully opened issue", "status": 201}
    else:
        send_message_ephemeral(channel_id, uid, MESSAGE.get('error_issue', ''))
        return {"message": "Error in opening issue", "status": status}
示例#3
0
def handle_message_answering(event_data):
    # Time stamp  of thread if present
    thread_ts = event_data.get('thread_ts', None)
    # Message time stamp
    reply_ts = event_data.get('ts', None)
    # If message is in a thread, then the UID of commenter of main message
    parent_uid = event_data.get('parent_user_id', None)
    # Current comment's author
    comment_user_uid = event_data.get('user', None)
    text = str(event_data.get('text', None))
    channel = event_data.get('channel', None)
    # Checking if it's a reply to a thread by any other user
    if thread_ts is not None and parent_uid != comment_user_uid:
        return {'message': 'Not handling replies made by others'}
    # If the message is in a thread and made by the parent commenter
    elif thread_ts is not None and parent_uid == comment_user_uid:
        reply_ts = thread_ts
    if channel == CHANNEL_LIST.get('intro'):  # pragma: no cover
        techs = techstack_vs_projects.keys()
        suggest_projects_set = set()
        search_text_tokens = word_tokenize(text.upper())
        # Finding all languages mentioned in comment common with the ones in Systers language list
        techs = list(set(search_text_tokens).intersection(set(techs)))
        for tech in techs:
            suggest_projects_set = suggest_projects_set.union(
                set(techstack_vs_projects[tech]))
        suggest_projects_list = list(suggest_projects_set)
        # No tech stack found in intro comment.
        if not suggest_projects_list and thread_ts is None:
            message = MESSAGE.get('answer_to_intro') % (
                MESSAGE.get('no_project'))
            send_message_thread(channel, message, reply_ts)
        elif suggest_projects_list:
            projects = ""
            for i, project in enumerate(suggest_projects_list):
                projects = projects + "\n" + str(
                    i + 1) + ". www.github.com/systers/" + project + ", "
            # Message is not in a thread. Reply with full message.
            if thread_ts is None:
                message = MESSAGE.get('answer_to_intro') % (
                    MESSAGE.get('projects_message') % projects[0:-2])
                send_message_thread(channel, message, reply_ts)
            # Message in thread. Reply with projects.
            elif thread_ts is not None:
                message = MESSAGE.get('projects_message') % projects[0:-2]
                send_message_thread(channel, message, reply_ts)
    # Answering some FAQs
    answer_keyword_faqs(text, channel, reply_ts)
    # Answering classification questions only on questions and intro and not in threads
    if thread_ts is None and (channel == CHANNEL_LIST.get('questions')
                              or channel == CHANNEL_LIST.get('intro')):
        luis_classifier(text, channel, reply_ts)
        return {'message': 'Sent for intent classification'}
    return {'message': 'Not sent for classification'}
示例#4
0
def collect_unreviewed_prs():  # pragma: no cover
    for key, value in repo_vs_channel_id_dict.iteritems():
        # Collect PRs for each repo
        pr_list = list_open_prs_from_repo('systers', key)
        if pr_list != '':
            # Constructing message( excluding the last comma from pr_list)
            message = MESSAGE.get('list_of_unreviewed_prs',
                                  '%s') % pr_list[0:-1]
            # Send pr_list to respective channels
            send_message_to_channels(value, message)
        else:
            send_message_to_channels(value,
                                     MESSAGE.get('no_unreviewed_prs', ""))
示例#5
0
def assign_issue_slack(data):
    result = is_maintainer_comment(data.get('user_id', ''))
    channel_id = data.get('channel_id', '')
    uid = data.get('user_id', '')
    if result.get('is_maintainer', False):
        params = data.get('text', '')
        tokens = params.split(' ')
        if params != '' and len(tokens) == 3:
            # The tokens are issue number, repo name, and assignee username
            is_issue_claimed_or_assigned = check_multiple_issue_claim(
                org_repo_owner, tokens[0], tokens[1])
            # Check if issue is approved
            is_issue_approved = check_approved_tag(org_repo_owner, tokens[0],
                                                   tokens[1])
            # If issue has been claimed, send message to the channel
            if is_issue_claimed_or_assigned:
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('already_claimed', ''))
                return {"message": "Issue already claimed"}
            # If issue has not been approved, send message to the channel
            if type(is_issue_approved) is dict:
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('wrong_info', ''))
                return {"message": "Wrong information provided", "status": 404}
            if not is_issue_approved:
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('not_approved', ''))
                return {"message": "Issue not approved"}
            # If issue is available, then check for assign status
            status = issue_assign(tokens[1], tokens[0], tokens[2],
                                  org_repo_owner)
            if status == 404:
                # Information given is wrong
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('wrong_info', ''))
                return {"message": "Wrong information provided", "status": 404}
            elif status == 200:  # pragma: no cover
                # Successful assignment
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('success', ''))
                return {"message": "Success", "status": 200}
            elif status == 500:  # pragma: no cover
                # Some internal error occured
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('error_slash_command', ''))
                return {
                    "message": "Author cannot approve an issue",
                    "status": 500
                }
        else:
            # Wrong format of command was used
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('correct_assign_format', ''))
            return {"message": "Wrong format of command"}
    else:
        # The commentor is not a maintainer
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('not_a_maintainer', ''))
        return {"message": "Not a maintainer"}
示例#6
0
def dm_new_users(data):
    # Get user id of the user who joined
    uid = data.get('event', {}).get('user', None)
    if uid is not None:
        body = {'user': uid}
        # Open a DM channel to the user. Request goes to im.open
        r = requests.post(dm_channel_open_url,
                          data=json.dumps(body),
                          headers=headers)
        response = r.json()
        if response.get('ok', False):
            # Get the channel just opened for DM
            dm_channel_id = response.get('channel', {}).get('id', '')
            if dm_channel_id != '':
                body = {
                    'username':
                    '******',
                    'as_user':
                    True,
                    'text':
                    MESSAGE.get('first_timer_message', 'Some error occured'),
                    'channel':
                    dm_channel_id
                }
                # Send a DM request
                r = requests.post(dm_chat_post_message_url,
                                  data=json.dumps(body),
                                  headers=headers)
                return {'message': 'Success', 'status': 200}
    return {'message': 'Data format wrong', 'status': 400}
示例#7
0
def issue_comment_approve_github(issue_number, repo_name, repo_owner,
                                 comment_author, is_from_slack):
    if not is_from_slack:
        issue_author = get_issue_author(repo_owner, repo_name, issue_number)
        if issue_author == comment_author:
            github_comment(MESSAGE.get('author_cannot_approve', ''),
                           repo_owner, repo_name, issue_number)
            return {'message': 'Author cannot approve.', 'status': 400}
    session = requests.Session()
    session.auth = (USERNAME, PASSWORD)
    # Name of label to be removed
    remove_label_name = '/Not%20Approved'
    # Label to be added
    label = '["issue-approved"]'
    request_url = add_label_url % (repo_owner, repo_name, issue_number)
    # Delete the not approved label first
    response = session.delete(request_url + remove_label_name, headers=headers)
    if response.status_code == 200 or response.status_code == 404:
        # Add the new label
        response = session.post(request_url, data=label, headers=headers)
        if response.status_code == 200:
            return {'message': 'Success', 'status': response.status_code}
        else:
            return {'message': 'Error', 'status': response.status_code}
    return {'message': 'Data provided is wrong', 'status': 400}
示例#8
0
def help_command():
    if request.headers['Content-Type'] == 'application/x-www-form-urlencoded':
        user_info = request.form
        send_message_ephemeral(user_info.get('channel_id', ''),
                               user_info.get('user_id', ''),
                               MESSAGE.get('help_message', ''))
        return Response(status=200)
示例#9
0
def slack_team_name_reply(data):
    message = data.get('event', {}).get('text', '')
    channel_id = data.get('event', {}).get('channel', '')
    uid = data.get('event', {}).get('user', '')
    # Check if query format is ok
    if message != '' and len(message.split('<@UASFP3GHW>')) >= 2:
        # Extracting the query text from message. Here <@UASFP3GHW> is the bot mention.
        query = message.split('<@UASFP3GHW>')[1].strip()
        team_details = slack_team_vs_repo_dict.get(channel_id, '')
        # Check if query is empty or if channel doesn't have a team.
        if query != '' and team_details != '':
            # This is a constant command which will always work
            if query == 'maintainer team name':  # pragma: no cover
                send_message_ephemeral(
                    channel_id, uid,
                    MESSAGE.get('slack_team_message') %
                    (team_details[0], team_details[1]))
                return {'message': 'Team name requested'}
            else:
                query = query.replace(' ', '%20')
                request_url = luis_agent_intent_classify_call % (
                    path_secret, api_key, query)
                response = requests.get(request_url).json()
                # Checking by matching intent. Keeping score high to prevent false positives.
                condition1 = response.get('topScoringIntent',
                                          {}).get('intent',
                                                  '') == 'Maintainers'
                condition2 = float(
                    response.get('topScoringIntent', {}).get('score',
                                                             '0')) > 0.965
                if condition1 and condition2:  # pragma: no cover
                    send_message_ephemeral(
                        channel_id, uid,
                        MESSAGE.get('slack_team_message') %
                        (team_details[0], team_details[1]))
                    return {'message': 'Team name requested'}
                else:
                    # If query isn't recognized, return default answer
                    send_message_ephemeral(channel_id, uid,
                                           MESSAGE.get('no_answer'))
                    return {'message': 'Not classified query'}
        elif team_details == '':
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('slack_team_DNE'))
            return {'message': 'Team does not exist in records.'}
    send_message_ephemeral(channel_id, uid, MESSAGE.get('wrong_query_format'))
    return {'message': 'Illegitimate query.'}
示例#10
0
def view_issue_slack(event_data):
    command_text = event_data.get('text', '')
    channel_id = event_data.get('channel_id', '')
    uid = event_data.get('user_id', '')
    tokens = command_text.strip().split(' ')
    if len(tokens) == 2:
        response = fetch_issue_body(org_repo_owner, tokens[0], tokens[1])
        if response.get('status', 404) == 200:
            send_message_ephemeral(channel_id, uid,
                                   response.get('issue_body', ''))
            return {'message': 'Success in viewing.'}
        else:
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('incorrect_info_provided', ''))
            return {'message': "Wrong info provided"}
    else:
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('error_view_command', ''))
        return {'message': "Error in using command"}
示例#11
0
def issue_claim_github(assignee, issue_number, repo_name, repo_owner):
    status = check_assignee_validity(repo_name, assignee, repo_owner)
    # Check if the assignee is valid
    if status == 404:
        # If member cant be assigned
        github_comment(MESSAGE.get('not_an_org_member', ''), repo_owner,
                       repo_name, issue_number)
        return {"message": "Not a member of the organization", "status": 404}
    if status == 204:
        # If member can be assigned an issue.
        issue_assign(issue_number, repo_name, assignee, repo_owner)
        return {"message": "Issue claimed", "status": 204}
    return {"status": status}
示例#12
0
def check_issue_template(repo_owner, repo_name, issue_number, body):
    if not are_issue_essential_components_present(body):
        session = requests.Session()
        session.auth = (USERNAME, PASSWORD)
        label = '["Template Mismatch"]'
        request_url = add_label_url % (repo_owner, repo_name, issue_number)
        response = session.post(request_url, data=label, headers=headers)
        github_comment(MESSAGE.get('template_mismatch', ''), repo_owner,
                       repo_name, issue_number)
        return {
            "message": "Issue Template mismatch",
            "label_status": response.status_code
        }
    return {"message": "Issue Template match"}
示例#13
0
def check_pr_template(pr_body, repo_owner, repo_name, pr_number):
    tokens = pr_body.split('\r\n')
    # Remove blank strings
    tokens = [s.strip() for s in tokens if s != '']
    # Necessary components in the PR template
    necessary_elements_set = {
        '### Description', '### Type of Change:',
        '### How Has This Been Tested?', '### Checklist:'
    }
    # Check if issue linking statement is present
    if 'Fixes #' not in pr_body:
        github_comment(MESSAGE.get('pr_not_linked_to_issue'), repo_owner,
                       repo_name, pr_number)
        close_pr(repo_owner, repo_name, pr_number)
        return False
    else:
        # Checking if issue number is provided
        for token in tokens:
            if 'Fixes #' in token:
                issue_number = token.split('Fixes #')[1]
                if not issue_number.isdigit():
                    github_comment(MESSAGE.get('pr_not_linked_to_issue'),
                                   repo_owner, repo_name, pr_number)
                    close_pr(repo_owner, repo_name, pr_number)
                    return False
    # Check if the template format has been followed and contents under any header isn't empty
    if set(tokens).intersection(
            necessary_elements_set) == necessary_elements_set:
        if tokens[tokens.index('### Description') + 1] != '### Type of Change:' and \
                tokens[tokens.index('### Type of Change:') + 1] != '### How Has This Been Tested?' and \
                tokens[tokens.index('### How Has This Been Tested?') + 1] != '### Checklist:' and \
                tokens[-1] != '### Checklist:':
            return True
    github_comment(MESSAGE.get('pr_template_not_followed'), repo_owner,
                   repo_name, pr_number)
    close_pr(repo_owner, repo_name, pr_number)
    return False
示例#14
0
def check_newcomer_requirements(uid, channel_id):
    response = get_detailed_profile(uid)
    if response.get('ok', False):
        profile = response.get('profile', '')
        get_github_username = get_github_username_profile(profile)
        github_profile_present = get_github_username.get(
            'github_profile_present', False)
        if github_profile_present and profile.get('first_name', "") != "" and profile.get('last_name', "") != "" \
                and profile.get('title', "") != "" and profile.get('image_original', "") != "" \
                and not profile.get('phone', "").isdigit():
            github_id = get_github_username.get('github_id', '')
            send_github_invite(github_id)
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('invite_sent', ''))
            return {"message": "Invitation sent"}
        else:
            send_message_ephemeral(
                channel_id, uid,
                MESSAGE.get('newcomer_requirement_incomplete', ''))
            return {"message": "Newcomer requirements incomplete"}
    else:
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('error_slash_command', ''))
        return {"message": "Error with slash command"}
示例#15
0
def open_issue_github(repo_owner, repo_name, issue_title, issue_description,
                      update_list_item, estimation, author):
    session = requests.Session()
    session.auth = (USERNAME, PASSWORD)
    request_url = open_issue_url % (repo_owner, repo_name)
    # JSON issue body.
    issue_request_body = {
        "title":
        "%s" % issue_title,
        "body":
        MESSAGE.get("issue_template") %
        (author, issue_description, update_list_item, estimation)
    }
    response = session.post(request_url,
                            json=issue_request_body,
                            headers=headers)
    return response.status_code
示例#16
0
def github_hook_receiver_function():
    if request.headers['Content-Type'] == 'application/json':
        data = request.json
        action = data.get('action', None)
        if action is not None:
            if (action == 'opened' or action == 'reopened') and data.get(
                    'pull_request', '') == '':
                # If it's an issue opened event and not PR opened event
                issue_number = data.get('issue', {}).get('number', '')
                repo_name = data.get('repository', {}).get('name', '')
                repo_owner = data.get('repository',
                                      {}).get('owner', {}).get('login', '')
                issue_body = data.get('issue', {}).get('body', '')
                # Label newly opened issue
                label_opened_issue(data)
                # Check if opened issue follows issue template
                check_issue_template(repo_owner, repo_name, issue_number,
                                     issue_body)
                return jsonify({'message': "New issue opened event"})
            elif action == 'created' and data.get('comment', '') != '':
                # If it's a issue comment event
                issue_number = data.get('issue', {}).get('number', '')
                repo_name = data.get('repository', {}).get('name', '')
                repo_owner = data.get('repository',
                                      {}).get('owner', {}).get('login', '')
                comment_body = data.get('comment', {}).get('body', '')
                tokens = comment_body.split(' ')
                commenter = data.get('comment', {}).get('user',
                                                        {}).get('login', '')
                author_association = data.get('comment',
                                              {}).get('author_association', '')
                is_issue_claimed_or_assigned = check_multiple_issue_claim(
                    repo_owner, repo_name, issue_number)
                # Check if the comment by coveralls
                if commenter == 'coveralls' and 'Coverage decreased' in comment_body:
                    github_comment(MESSAGE.get('add_tests', ''), repo_owner,
                                   repo_name, issue_number)
                    return jsonify({'message': "Coveralls comment"})

                # If comment is for approving issue
                if comment_body.lower().strip().startswith('@sys-bot approve') or \
                        is_variant_of_approve(comment_body.lower()):
                    issue_comment_approve_github(issue_number, repo_name,
                                                 repo_owner, commenter, False)
                    return jsonify({"message": "Approve command"})

                # If comment is to assign issue
                if comment_body.lower().strip().startswith('@sys-bot assign'):
                    is_approved = check_approved_tag(repo_owner, repo_name,
                                                     issue_number)
                    if len(tokens) == 3 and not is_issue_claimed_or_assigned and \
                            (author_association == 'COLLABORATOR' or author_association == 'OWNER') and is_approved:
                        issue_assign(issue_number, repo_name, tokens[2],
                                     repo_owner)  # pragma: no cover
                    elif len(tokens) != 3 and not is_issue_claimed_or_assigned:
                        github_comment(MESSAGE.get('wrong_format_github', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Wrong command format"})
                    elif not is_approved:
                        github_comment(MESSAGE.get('not_approved', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Issue not approved"})
                    elif is_issue_claimed_or_assigned:
                        github_comment(MESSAGE.get('already_claimed', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Issue already claimed"})
                    elif author_association != 'COLLABORATOR' and author_association != 'OWNER':
                        github_comment(MESSAGE.get('no_permission', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Not permitted"})

                # If comment is to claim issue
                if comment_body.lower().strip().startswith('@sys-bot claim'):
                    is_approved = check_approved_tag(repo_owner, repo_name,
                                                     issue_number)
                    if len(
                            tokens
                    ) == 2 and not is_issue_claimed_or_assigned and is_approved:  # pragma: no cover
                        assignee = commenter
                        issue_claim_github(assignee, issue_number, repo_name,
                                           repo_owner)
                    elif len(tokens) != 2 and not is_issue_claimed_or_assigned:
                        github_comment(MESSAGE.get('wrong_format_github', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Wrong command format"})
                    elif is_issue_claimed_or_assigned:
                        github_comment(MESSAGE.get('already_claimed', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Already claimed"})
                    elif not is_approved:
                        github_comment(MESSAGE.get('not_approved', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Issue not approved"})

                # If comment is to unclaim an issue
                if comment_body.lower().strip().startswith('@sys-bot unclaim'):
                    if len(tokens) == 2:
                        assignee = commenter
                        unassign_issue(repo_owner, repo_name, issue_number,
                                       assignee)
                        return jsonify({"message": "Issue unclaimed"})
                    else:
                        github_comment(MESSAGE.get('wrong_format_github', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Wrong command format"})
                # If comment is to unassign an issue
                if comment_body.lower().strip().startswith(
                        '@sys-bot unassign'):
                    if len(tokens) == 3 and (author_association
                                             == 'COLLABORATOR'
                                             or author_association == 'OWNER'):
                        unassign_issue(repo_owner, repo_name, issue_number,
                                       tokens[2])
                        return jsonify({"message": "Issue unassigned"})
                    elif len(tokens) == 3 and (
                            author_association != 'COLLABORATOR'
                            and author_association != 'OWNER'):
                        github_comment(MESSAGE.get('no_permission', ''),
                                       repo_owner, repo_name, issue_number)
                    else:
                        github_comment(MESSAGE.get('wrong_format_github', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Wrong command format"})

                # If comment is for labelling an issue
                if comment_body.lower().strip().startswith("@sys-bot label"):
                    if len(tokens) < 3:
                        github_comment(MESSAGE.get('wrong_format_github', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Wrong command format"})
                    elif len(tokens) >= 3 and (
                            author_association != 'COLLABORATOR'
                            and author_association != 'OWNER'):
                        github_comment(MESSAGE.get('no_permission', ''),
                                       repo_owner, repo_name, issue_number)
                        return jsonify({"message": "Not permitted"})
                    else:
                        response = label_list_issue(repo_owner, repo_name,
                                                    issue_number, comment_body)
                        return jsonify({"message": response.get("message")})
            elif (action == 'opened' or action
                  == 'reopened') and data.get('pull_request', '') != '':
                # If a new PR has been sent
                pr_number = data.get('number', '')
                repo_name = data.get('repository', {}).get('name', '')
                repo_owner = data.get('repository',
                                      {}).get('owner', {}).get('login', '')
                pr_body = data.get('pull_request', {}).get('body', '')
                is_template_followed = check_pr_template(
                    pr_body, repo_owner, repo_name, pr_number)
                if is_template_followed:
                    github_pull_request_label(pr_number, repo_name, repo_owner)
                    # Extract the issue number mentioned in PR body if PR follows template
                    issue_number = pr_body.split('Fixes #')[1].split(
                        '\r\n')[0].strip()
                    is_issue_approved = check_approved_tag(
                        repo_owner, repo_name, issue_number)
                    if not is_issue_approved:
                        github_comment(
                            MESSAGE.get('pr_to_unapproved_issue', ''),
                            repo_owner, repo_name, pr_number)
                        close_pr(repo_owner, repo_name, pr_number)
                        return jsonify(
                            {"message": "PR sent to unapproved issue"})
                else:
                    return jsonify({"message": "PR template not followed"})
            elif action == "submitted" and data.get("review", "") != "":
                pr_reviewed_label(data)
        return jsonify({"message": "Unknown event"})
示例#17
0
def approve_issue_label_slack(data):
    channel_id = data.get('channel_id', '')
    uid = data.get('user_id', '')
    result = is_maintainer_comment(uid)
    response = get_detailed_profile(uid)
    if response.get('ok', False):
        profile = response.get('profile', '')
        get_github_username = get_github_username_profile(profile)
        github_profile_present = get_github_username.get(
            'github_profile_present', False)
        if not github_profile_present:
            send_message_ephemeral(
                channel_id, uid,
                MESSAGE.get('newcomer_requirement_incomplete', ''))
            return {"message": "Newcomer Requirement Incomplete"}
        else:
            github_id = get_github_username.get('github_id', '')
            if result.get('is_maintainer', False):
                params = data.get('text', '')
                if params != '' and len(params.split(' ')) == 2:
                    issue_author = get_issue_author(org_repo_owner,
                                                    params.split(' ')[0],
                                                    params.split(' ')[1])
                    if issue_author == github_id:
                        send_message_ephemeral(
                            channel_id, uid,
                            MESSAGE.get('author_cannot_approve', ''))
                        return {"message": "Author cannot approve an issue"}
                    response = issue_comment_approve_github(
                        params.split(' ')[1],
                        params.split(' ')[0], org_repo_owner, github_id, True)
                    status = response.get('status', 500)
                    if status == 404:
                        # Information given is wrong
                        send_message_ephemeral(channel_id, uid,
                                               MESSAGE.get('wrong_info', ''))
                        return {
                            "message": "Information provided is wrong",
                            "status": 404
                        }
                    elif status == 200:  # pragma: no cover
                        # Successful labeling
                        send_message_ephemeral(channel_id, uid,
                                               MESSAGE.get('success', ''))
                        return {"message": "Success", "status": 200}
                    elif status == 500:  # pragma: no cover
                        # Some internal error occured
                        send_message_ephemeral(
                            channel_id, uid,
                            MESSAGE.get('error_slash_command', ''))
                        return {
                            "message": "Error with slash command",
                            "status": 500
                        }
                else:
                    # Wrong format of command was used
                    send_message_ephemeral(
                        channel_id, uid,
                        MESSAGE.get('correct_approve_format', ''))
                    return {
                        "message": "Wrong parameters for for approval command"
                    }
            else:
                # The commentor is not a maintainer
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('not_a_maintainer', ''))
                return {"message": "Non-maintainer cannot use the command"}
    else:
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('error_slash_command', ''))
        return {"message": "Error with slash command"}
示例#18
0
def claim_issue_slack(data):
    params = data.get('text', '')
    tokens = params.split(' ')
    channel_id = data.get('channel_id', '')
    uid = data.get('user_id', '')
    if params != '' and (len(tokens) == 3 or len(tokens) == 2):
        # The tokens are issue number, repo name, and claimant's username
        is_issue_claimed_or_assigned = check_multiple_issue_claim(
            org_repo_owner, tokens[0], tokens[1])
        # Check if issue is approved
        is_issue_approved = check_approved_tag(org_repo_owner, tokens[0],
                                               tokens[1])
        # If issue has been claimed, send message to the channel
        if is_issue_claimed_or_assigned:
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('already_claimed', ''))
            return {"message": "Issue already claimed"}
        # If issue has not been approved, send message to the channel
        if isinstance(is_issue_approved, dict):
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('wrong_info', ''))
            return {"message": "Wrong information provided", "status": 404}
        if not is_issue_approved:
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('not_approved', ''))
            return {"message": "Issue not approved"}
        # If the format /sysbot_claim <repo_name> <issue_number> is used
        if len(tokens) == 2:
            response = get_detailed_profile(uid)
            if response.get('ok', False):
                response = get_github_username_profile(
                    response.get('profile', {}))
                if response.get('github_profile_present', False):
                    # Find if the username is present in Slack profile
                    github_username = response.get('github_id', '')
                else:
                    send_message_ephemeral(
                        channel_id, uid,
                        MESSAGE.get('error_claim_alternate', ''))
                    return {"message": "Incomplete profile for using command"}
            else:
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('error_slash_command', ''))
                return {"message": "Error in command parameters"}
        else:
            github_username = tokens[2]

        # If issue is available, then check for assign status
        status = issue_assign(tokens[1], tokens[0], github_username,
                              org_repo_owner)
        # If a 404 error status is raised, check if the assignee can be assigned.
        if status == 404:
            # Check assignee status
            assignee_status = check_assignee_validity(tokens[0],
                                                      github_username,
                                                      org_repo_owner)
            if assignee_status == 404:
                # Can't be assigned as not a member
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('not_a_member', ''))
                return {"message": "Not a member", "status": 404}
            else:
                # Information given is wrong
                send_message_ephemeral(channel_id, uid,
                                       MESSAGE.get('wrong_info', ''))
                return {"message": "Wrong information provided"}
        elif status == 200:  # pragma: no cover
            # Successful claim
            send_message_ephemeral(channel_id, uid, MESSAGE.get('success', ''))
            return {"message": "Success", "status": 404}
        elif status == 500:  # pragma: no cover
            # Some internal error occured
            send_message_ephemeral(channel_id, uid,
                                   MESSAGE.get('error_slash_command', ''))
            return {"message": "Error slash command", "status": 500}
    else:
        # Wrong format of command was used
        send_message_ephemeral(channel_id, uid,
                               MESSAGE.get('correct_claim_format', ''))
        return {"message": "Correct claim format"}