Exemple #1
0
def proxy_comments(number):
    """XHR endpoint for GitHub issue comments.

    * GET an issue comments
    * POST a comment on an issue (only as an authorized GitHub user)
    """
    params = request.args.copy()
    path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
    if request.method == 'POST' and g.user:
        new_comment = api_request('post',
                                  path,
                                  params=params,
                                  data=get_comment_data(request.data),
                                  mime_type=JSON_MIME_HTML)
        return get_html_comments(new_comment)
    else:
        # TODO: handle the (rare) case for more than 1 page of comments
        # for now, we just get the first 100 and rely on the client to
        # fetch more
        params.update({'per_page': 100})
        comments_data = api_request('get',
                                    path,
                                    params=params,
                                    mime_type=JSON_MIME_HTML)
        comments_status = comments_data[1:2]
        if comments_status != 304:
            return get_html_comments(comments_data)
        else:
            # in the case of a 304, the browser cache will handle it.
            return '', 304, get_response_headers(comments_data, HTML_MIME)
Exemple #2
0
def proxy_comments(number):
    '''XHR endpoint to get issues comments from GitHub.

    Either as an authed user, or as one of our proxy bots.
    '''
    if request.method == 'POST':
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('post', path, data=get_comment_data(request.data))
    else:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('get', path)
Exemple #3
0
def proxy_comments(number):
    '''XHR endpoint to get issues comments from GitHub.

    Either as an authed user, or as one of our proxy bots.
    '''
    if request.method == 'POST':
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('post', path, data=get_comment_data(request.data))
    else:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('get', path)
Exemple #4
0
def proxy_comments(number):
    """XHR endpoint to get issues comments from GitHub.

    Either as an authed user, or as one of our proxy bots.
    """
    params = request.args.copy()
    if request.method == 'POST' and g.user:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('post', path, params=params,
                           data=get_comment_data(request.data))
    else:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('get', path, params=params)
Exemple #5
0
def proxy_comments(number):
    """XHR endpoint to get issues comments from GitHub.

    Either as an authed user, or as one of our proxy bots.
    """
    params = request.args.copy()
    if request.method == 'POST' and g.user:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('post', path, params=params,
                           data=get_comment_data(request.data))
    else:
        path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number)
        return api_request('get', path, params=params)
Exemple #6
0
def get_issue_category(issue_category):
    """Return all issues for a specific category."""
    category_list = app.config['OPEN_STATUSES']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()
    if issue_category in category_list:
        STATUSES = app.config['STATUSES']
        params.add('milestone', STATUSES[issue_category]['id'])
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #7
0
def get_issue_category(issue_category):
    """Return all issues for a specific category."""
    category_list = app.config['OPEN_STATUSES']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()
    if issue_category in category_list:
        STATUSES = app.config['STATUSES']
        params.add('milestone', STATUSES[issue_category]['id'])
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #8
0
def get_search_results(query_string=None, params=None):
    """XHR endpoint to get results from GitHub's Search API.

    We're specifically searching "issues" here, which seems to make the most
    sense. Note that the rate limit is different for Search: 30 requests per
    minute.

    If a user hits the rate limit, the Flask Limiter extension will send a
    429. See @app.error_handler(429) in views.py.

    This method can take a query_string argument, to be called from other
    endpoints, or the query_string can be passed in via the Request object.
    """
    params = params or request.args.copy()
    query_string = query_string or params.get('q')
    # Fail early if no appropriate query_string
    if not query_string:
        abort(404)

    # restrict results to our repo.
    query_string += " repo:{0}".format(REPO_PATH)
    params['q'] = query_string

    # convert issues api to search api params here.
    params = normalize_api_params(params)
    path = 'search/issues'
    return api_request('get', path, params=params, mime_type=JSON_MIME_HTML)
Exemple #9
0
def get_rate_limit():
    '''Endpoint to display the current GitHub API rate limit.

    Will display for the logged in user, or webcompat-bot if not logged in.
    See https://developer.github.com/v3/rate_limit/.
    '''
    return api_request('get', 'rate_limit')
Exemple #10
0
def proxy_issue(number):
    '''XHR endpoint to get issue data from GitHub.

    either as an authed user, or as one of our proxy bots.
    '''
    path = 'repos/{0}/{1}'.format(ISSUES_PATH, number)
    return api_request('get', path)
Exemple #11
0
def proxy_issue(number):
    """XHR endpoint to get issue data from GitHub.

    either as an authed user, or as one of our proxy bots.
    """
    path = 'repos/{0}/{1}'.format(ISSUES_PATH, number)
    return api_request('get', path, mime_type=JSON_MIME_HTML)
Exemple #12
0
def get_rate_limit():
    '''Endpoint to display the current GitHub API rate limit.

    Will display for the logged in user, or webcompat-bot if not logged in.
    See https://developer.github.com/v3/rate_limit/.
    '''
    return api_request('get', 'rate_limit')
Exemple #13
0
def proxy_issue(number):
    """XHR endpoint to get issue data from GitHub.

    either as an authed user, or as one of our proxy bots.
    """
    path = 'repos/{0}/{1}'.format(ISSUES_PATH, number)
    return api_request('get', path)
Exemple #14
0
def get_search_results(query_string=None, params=None):
    """XHR endpoint to get results from GitHub's Search API.

    We're specifically searching "issues" here, which seems to make the most
    sense. Note that the rate limit is different for Search: 30 requests per
    minute.

    If a user hits the rate limit, the Flask Limiter extension will send a
    429. See @app.error_handler(429) in views.py.

    This method can take a query_string argument, to be called from other
    endpoints, or the query_string can be passed in via the Request object.
    """
    params = params or request.args.copy()
    query_string = query_string or params.get('q')
    # Fail early if no appropriate query_string
    if not query_string:
        abort(404)

    # restrict results to our repo.
    query_string += " repo:{0}".format(REPO_PATH)
    params['q'] = query_string

    # convert issues api to search api params here.
    params = normalize_api_params(params)
    path = 'search/issues'
    return api_request('get', path, params=params,
                       mime_type=JSON_MIME_HTML)
Exemple #15
0
def get_issue_category(issue_category):
    '''Return all issues for a specific category.

    issue_category can be of N types:
    * new
    * closed
    * contactready
    * needscontact
    * needsdiagnosis
    * sitewait
    '''
    category_list = [
        'contactready', 'needscontact', 'needsdiagnosis', 'sitewait'
    ]
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()

    if issue_category in category_list:
        # add "status-" before the filter param to match the naming scheme
        # of the repo labels.
        params.add('labels', 'status-' + issue_category)
        # Turns out the GitHub API considers &labels=x&labels=y an OR query
        # &labels=x,y is an AND query. Join the labels with a comma
        params['labels'] = ','.join(params.getlist('labels'))
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    # Note that 'new' here is primarily used on the homepage.
    # For paginated results on the /issues page, see /issues/search/new.
    elif issue_category == 'new':
        issues = api_request('get', issues_path, params=params)
        # api_request returns a tuple of format:
        #       (content, status_code, response_headers)
        # So we make a dict here for improved readability
        content, status_code, response_headers = issues
        if status_code != 304:
            content = filter_new(json.loads(content))
        return (content, status_code, response_headers)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #16
0
def get_issue_category(issue_category):
    '''Return all issues for a specific category.

    issue_category can be of N types:
    * new
    * closed
    * contactready
    * needscontact
    * needsdiagnosis
    * sitewait
    '''
    category_list = ['contactready', 'needscontact',
                     'needsdiagnosis', 'sitewait']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()

    if issue_category in category_list:
        # add "status-" before the filter param to match the naming scheme
        # of the repo labels.
        params['labels'] = 'status-' + issue_category
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    # Note that 'new' here is primarily used on the homepage.
    # For paginated results on the /issues page, see /issues/search/new.
    elif issue_category == 'new':
        issues = api_request('get', issues_path, params=params)
        # api_request returns a tuple of format:
        #       (content, status_code, response_headers)
        # So we make a dict here for improved readability
        new_issues = {
            'content': filter_new(json.loads(issues[0])),
            'status_code': issues[1],
            'response_headers': issues[2]
        }
        return (new_issues['content'], new_issues['status_code'],
                new_issues['response_headers'])
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
def get_issue_category(issue_category):
    '''Return all issues for a specific category.

    issue_category can be of N types:
    * new
    * closed
    * contactready
    * needscontact
    * needsdiagnosis
    * sitewait
    '''
    category_list = ['contactready', 'needscontact',
                     'needsdiagnosis', 'sitewait']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()

    if issue_category in category_list:
        # add "status-" before the filter param to match the naming scheme
        # of the repo labels.
        params.add('labels', 'status-' + issue_category)
        # Turns out the GitHub API considers &labels=x&labels=y an OR query
        # &labels=x,y is an AND query. Join the labels with a comma
        params['labels'] = ','.join(params.getlist('labels'))
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    # Note that 'new' here is primarily used on the homepage.
    # For paginated results on the /issues page, see /issues/search/new.
    elif issue_category == 'new':
        issues = api_request('get', issues_path, params=params)
        # api_request returns a tuple of format:
        #       (content, status_code, response_headers)
        # So we make a dict here for improved readability
        content, status_code, response_headers = issues
        if status_code != 304:
            content = filter_new(json.loads(content))
        return (content, status_code, response_headers)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #18
0
def get_issue_category(issue_category):
    '''Return all issues for a specific category.

    issue_category can be of N types:
    * needstriage
    * closed
    * contactready
    * needscontact
    * needsdiagnosis
    * sitewait
    '''
    category_list = [
        'contactready', 'needscontact', 'needsdiagnosis', 'needstriage',
        'sitewait'
    ]
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()

    if issue_category in category_list:
        # add "status-" before the filter param to match the naming scheme
        # of the repo labels.
        params.add('labels', 'status-' + issue_category)
        # Turns out the GitHub API considers &labels=x&labels=y an OR query
        # &labels=x,y is an AND query. Join the labels with a comma
        params['labels'] = ','.join(params.getlist('labels'))
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    # Note that 'needstriage' here is primarily used on the homepage.
    # For paginated results on the /issues page,
    # see /issues/search/needstriage.
    # We abort with 301 here because the new endpoint has
    # been replaced with needstriage.
    elif issue_category == 'new':
        abort(301)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #19
0
def get_issue_category(issue_category):
    '''Return all issues for a specific category.

    issue_category can be of N types:
    * needstriage
    * closed
    * contactready
    * needscontact
    * needsdiagnosis
    * sitewait
    '''
    category_list = ['contactready', 'needscontact',
                     'needsdiagnosis', 'needstriage', 'sitewait']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()

    if issue_category in category_list:
        # add "status-" before the filter param to match the naming scheme
        # of the repo labels.
        params.add('labels', 'status-' + issue_category)
        # Turns out the GitHub API considers &labels=x&labels=y an OR query
        # &labels=x,y is an AND query. Join the labels with a comma
        params['labels'] = ','.join(params.getlist('labels'))
        return api_request('get', issues_path, params=params)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get', issues_path, params=params)
    # Note that 'needstriage' here is primarily used on the homepage.
    # For paginated results on the /issues page,
    # see /issues/search/needstriage.
    # We abort with 301 here because the new endpoint has
    # been replaced with needstriage.
    elif issue_category == 'new':
        abort(301)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #20
0
def proxy_issues():
    """List all issues from GitHub on the API endpoint."""
    params = request.args.copy()

    # If there's a q param, then we need to use the Search API
    # and load those results. For logged in users, we handle this at the
    # server level.
    if g.user and params.get('q'):
        return get_search_results(params.get('q'), params)
    # Non-authed users should never get here--the request is made to
    # GitHub client-side)--but return out of paranoia anyways.
    elif params.get('q'):
        abort(404)
    path = 'repos/{0}'.format(ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #21
0
def get_issue_category(issue_category, other_params=None):
    """Return all issues for a specific category."""
    category_list = app.config['OPEN_STATUSES']
    issues_path = 'repos/{0}'.format(ISSUES_PATH)
    params = request.args.copy()
    # Used by the dashboard to adjust the list of issues
    if other_params:
        params.update(other_params)
    if issue_category in category_list:
        STATUSES = app.config['STATUSES']
        params.add('milestone', STATUSES[issue_category]['id'])
        return api_request('get',
                           issues_path,
                           params=params,
                           mime_type=JSON_MIME_HTML)
    elif issue_category == 'closed':
        params['state'] = 'closed'
        return api_request('get',
                           issues_path,
                           params=params,
                           mime_type=JSON_MIME_HTML)
    else:
        # The path doesn’t exist. 404 Not Found.
        abort(404)
Exemple #22
0
def proxy_issues():
    """List all issues from GitHub on the API endpoint."""
    params = request.args.copy()

    # If there's a q param, then we need to use the Search API
    # and load those results. For logged in users, we handle this at the
    # server level.
    if g.user and params.get('q'):
        return get_search_results(params.get('q'), params)
    # Non-authed users should never get here--the request is made to
    # GitHub client-side)--but return out of paranoia anyways.
    elif params.get('q'):
        abort(404)
    path = 'repos/{0}'.format(ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #23
0
def get_user_activity_issues(username, parameter):
    '''API endpoint to return issues related to a user.

    cf. https://developer.github.com/v3/issues/#list-issues-for-a-repository
    This is only used for "creator" and "mentioned" right now.

    Any logged in user can see details for any other logged in user. We can
    extend this to non-logged in users in the future if we want.
    '''
    if not g.user:
        abort(401)
    # copy the params so we can add to the dict.
    params = request.args.copy()
    params['state'] = 'all'
    params['{0}'.format(parameter)] = '{0}'.format(username)
    path = 'repos/{path}'.format(path=ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #24
0
def get_user_activity_issues(username, parameter):
    """Return issues related to a user at the API endpoint.

    cf. https://developer.github.com/v3/issues/#list-issues-for-a-repository
    This is only used for "creator" and "mentioned" right now.

    Any logged in user can see details for any other logged in user. We can
    extend this to non-logged in users in the future if we want.
    """
    if not g.user:
        abort(401)
    # copy the params so we can add to the dict.
    params = request.args.copy()
    params['state'] = 'all'
    params['{0}'.format(parameter)] = '{0}'.format(username)
    path = 'repos/{path}'.format(path=ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #25
0
def get_user_activity_issues(username, parameter):
    """Return issues related to a user at the API endpoint.

    cf. https://developer.github.com/v3/issues/#list-issues-for-a-repository
    This is used for "creator" and "mentioned". A special "needsinfo" parameter
    value is converted into a request for labels of the format:

    `status-needsinfo-username`

    Any logged in user can see details for any other logged in user. We can
    extend this to non-logged in users in the future if we want.
    """
    if not g.user:
        abort(401)
    # copy the params so we can add to the dict.
    params = request.args.copy()
    params['state'] = 'all'
    if parameter == 'needsinfo':
        params['labels'] = 'status-needsinfo-{0}'.format(username)
    else:
        params[parameter] = username
    path = 'repos/{path}'.format(path=ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #26
0
def get_user_activity_issues(username, parameter):
    """Return issues related to a user at the API endpoint.

    cf. https://developer.github.com/v3/issues/#list-issues-for-a-repository
    This is used for "creator" and "mentioned". A special "needsinfo" parameter
    value is converted into a request for labels of the format:

    `status-needsinfo-username`

    Any logged in user can see details for any other logged in user. We can
    extend this to non-logged in users in the future if we want.
    """
    if not g.user:
        abort(401)
    # copy the params so we can add to the dict.
    params = request.args.copy()
    params['state'] = 'all'
    if parameter == 'needsinfo':
        params['labels'] = 'status-needsinfo-{0}'.format(username)
    else:
        params[parameter] = username
    path = 'repos/{path}'.format(path=ISSUES_PATH)
    return api_request('get', path, params=params)
Exemple #27
0
def get_repo_labels():
    """XHR endpoint to get all possible labels in a repo."""
    params = request.args.copy()
    path = 'repos/{0}/labels'.format(REPO_PATH)
    return api_request('get', path, params=params)
Exemple #28
0
def get_repo_labels():
    """XHR endpoint to get all possible labels in a repo."""
    params = request.args.copy()
    path = 'repos/{0}/labels'.format(REPO_PATH)
    return api_request('get', path, params=params)