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': try: comment_data = json.loads(request.data) body = json.dumps({"body": comment_data['rawBody']}) path = 'repos/{0}/{1}/comments'.format(REPO_URI, number) comment = github.raw_request('POST', path, data=body) return (json.dumps(comment.json()), comment.status_code, { 'content-type': JSON_MIME }) except GitHubError as e: print('GitHubError: ', e.response.status_code) return (':(', e.response.status_code) else: if g.user: comments = github.raw_request( 'GET', 'repos/{0}/{1}/comments'.format(app.config['ISSUES_REPO_URI'], number)) else: comments = proxy_request('get', '/{0}/comments'.format(number)) return (comments.content, comments.status_code, get_headers(comments))
def get_search_results(query_string=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. Not cached. ''' search_uri = 'https://api.github.com/search/issues' # TODO: handle sort and order parameters. params = request.args.copy() if query_string is None: query_string = params.get('q') # restrict results to our repo. query_string += " repo:{0}".format(REPO_PATH) params['q'] = query_string if g.user: request_headers = get_request_headers(g.request_headers) results = github.raw_request('GET', 'search/issues', params=params, headers=request_headers) else: results = proxy_request('get', params=params, uri=search_uri) return (results.content, results.status_code, get_headers(results))
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. Not cached. """ params = params or request.args.copy() query_string = query_string or params.get("q") search_uri = "https://api.github.com/search/issues" # 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) request_headers = get_request_headers(g.request_headers) if g.user: results = github.raw_request("GET", "search/issues", params=params, headers=request_headers) else: results = proxy_request("get", params=params, uri=search_uri, headers=request_headers) return (results.content, results.status_code, get_headers(results))
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": try: comment_data = json.loads(request.data) body = json.dumps({"body": comment_data["rawBody"]}) path = "repos/{0}/{1}/comments".format(ISSUES_PATH, number) comment = github.raw_request("POST", path, data=body) return (json.dumps(comment.json()), comment.status_code, {"content-type": JSON_MIME}) except GitHubError as e: print("GitHubError: ", e.response.status_code) return (":(", e.response.status_code) else: request_headers = get_request_headers(g.request_headers) if g.user: comments = github.raw_request( "GET", "repos/{0}/{1}/comments".format(ISSUES_PATH, number), headers=request_headers ) else: comments = proxy_request("get", "/{0}/comments".format(number), headers=request_headers) return (comments.content, comments.status_code, get_headers(comments))
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': try: comment_data = json.loads(request.data) body = json.dumps({"body": comment_data['rawBody']}) path = 'repos/{0}/{1}/comments'.format(ISSUES_PATH, number) comment = github.raw_request('POST', path, data=body) return (json.dumps(comment.json()), comment.status_code, {'content-type': JSON_MIME}) except GitHubError as e: print('GitHubError: ', e.response.status_code) return (':(', e.response.status_code) else: if g.user: request_headers = get_request_headers(g.request_headers) comments = github.raw_request( 'GET', 'repos/{0}/{1}/comments'.format( ISSUES_PATH, number), headers=request_headers ) else: comments = proxy_request('get', '/{0}/comments'.format(number)) return (comments.content, comments.status_code, get_headers(comments))
def edit_issue(number): """XHR endpoint to push back edits to GitHub for a single issue. Note: this is always proxied to allow any logged in user to be able to edit issues. """ edit = proxy_request("patch", "/{0}".format(number), data=request.data) return (edit.content, edit.status_code, {"content-type": JSON_MIME})
def edit_issue(number): '''XHR endpoint to push back edits to GitHub for a single issue. Note: this is always proxied to allow any logged in user to be able to edit issues. ''' edit = proxy_request('patch', '/{0}'.format(number), data=request.data) return (edit.content, edit.status_code, {'content-type': JSON_MIME})
def get_issue_category(issue_category): '''Return all issues for a specific category. issue_category can be of x types: * new * contactready * 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 if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) elif issue_category == 'closed': params['state'] = 'closed' if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) # Note that 'new' here is primarily used on the hompage. # For paginated results on the /issues page, see /issues/search/new. elif issue_category == 'new': if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) # Do not send random JSON to filter_new if issues.status_code == 200: return (filter_new(json.loads(issues.content)), issues.status_code, get_headers(issues)) else: return ({}, issues.status_code, get_headers(issues)) else: # The path doesn’t exist. 404 Not Found. abort(404) return (issues.content, issues.status_code, get_headers(issues))
def get_issue_category(issue_category): '''Return all issues for a specific category. issue_category can be of x types: * new * contactready * 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 if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) elif issue_category == 'closed': params['state'] = 'closed' if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', 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': if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) # Do not send random JSON to filter_new if issues.status_code == 200: return (filter_new(json.loads(issues.content)), issues.status_code, get_headers(issues)) else: return ({}, issues.status_code, get_headers(issues)) else: # The path doesn’t exist. 404 Not Found. abort(404) return (issues.content, issues.status_code, get_headers(issues))
def get_issue_category(issue_category): """Return all issues for a specific category. issue_category can be of x types: * new * contactready * 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 if g.user: issues = github.raw_request("GET", issues_path, params=params) else: issues = proxy_request("get", params=params) elif issue_category == "closed": params["state"] = "closed" if g.user: issues = github.raw_request("GET", issues_path, params=params) else: issues = proxy_request("get", params=params) # Note that 'new' here is primarily used on the hompage. # For paginated results on the /issues page, see /issues/search/new. elif issue_category == "new": if g.user: issues = github.raw_request("GET", issues_path, params=params) else: issues = proxy_request("get", params=params) # Do not send random JSON to filter_new if issues.status_code == 200: return (filter_new(json.loads(issues.content)), issues.status_code, get_headers(issues)) else: return ({}, issues.status_code, get_headers(issues)) else: # The path doesn’t exist. 404 Not Found. abort(404) return (issues.content, issues.status_code, get_headers(issues))
def proxy_issues(): '''API endpoint to list all issues from GitHub. Cached for 5 minutes. ''' if g.user: issues = github.get('repos/{0}'.format(REPO_URI)) else: issues = proxy_request('get') return json.dumps(issues)
def proxy_issues(): '''API endpoint to list all issues from GitHub.''' params = request.args.copy() if g.user: issues = github.raw_request('GET', 'repos/{0}'.format(ISSUES_PATH), params=params) else: issues = proxy_request('get', params=params) return (issues.content, issues.status_code, get_headers(issues))
def get_issue_category(issue_category): '''Return all issues for a specific category. issue_category can be of x types: * untriaged (We take care in case there’s no bug) * contactready * needsdiagnosis * sitewait ''' category_list = ['contactready', 'needsdiagnosis', 'sitewait'] issues_path = 'repos/{0}'.format(ISSUES_PATH) params = request.args.copy() if issue_category in category_list: params['labels'] = issue_category if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) elif issue_category == 'closed': params['state'] = 'closed' if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) # Note that 'untriaged' here is primarily used on the hompage. # For paginated results on the /issues page, see /issues/search/untriaged. elif issue_category == 'untriaged': if g.user: issues = github.raw_request('GET', issues_path, params=params) else: issues = proxy_request('get', params=params) # Do not send random JSON to filter_untriaged if issues.status_code == 200: return (filter_untriaged(json.loads(issues.content)), issues.status_code, get_headers(issues)) else: return ({}, issues.status_code, get_headers(issues)) else: # The path doesn’t exist. 404 Not Found. abort(404) return (issues.content, issues.status_code, get_headers(issues))
def get_sitewait(): '''Return all issues with a "sitewait" label. Cached for 5 minutes. ''' if g.user: path = 'repos/{0}?labels=sitewait'.format(REPO_URI) issues = github.raw_request('GET', path) else: issues = proxy_request('get', '?labels=sitewait') return (issues.content, issues.status_code, get_headers(issues))
def proxy_issue(number): '''XHR endpoint to get issue data from GitHub. either as an authed user, or as one of our proxy bots. ''' if g.user: issue = github.raw_request('GET', 'repos/{0}/{1}'.format( app.config['ISSUES_REPO_URI'], number)) else: issue = proxy_request('get', '/{0}'.format(number)) return (issue.content, issue.status_code, get_headers(issue))
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/. ''' if g.user: rl = github.raw_request('GET', 'rate_limit') else: rl = proxy_request('get', uri='https://api.github.com/rate_limit') return rl.content
def proxy_issue(number): """XHR endpoint to get issue data from GitHub. either as an authed user, or as one of our proxy bots. """ request_headers = get_request_headers(g.request_headers) if g.user: issue = github.raw_request("GET", "repos/{0}/{1}".format(ISSUES_PATH, number), headers=request_headers) else: issue = proxy_request("get", "/{0}".format(number), headers=request_headers) return (issue.content, issue.status_code, get_headers(issue))
def proxy_issue(number): '''XHR endpoint to get issue data from GitHub. either as an authed user, or as one of our proxy bots. ''' if g.user: issue = github.raw_request( 'GET', 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], number)) else: issue = proxy_request('get', '/{0}'.format(number)) return (issue.content, issue.status_code, get_headers(issue))
def modify_labels(number): """XHR endpoint to modify issue labels. Sending in an empty array removes them all as well. This method is always proxied because non-repo collabs can't normally edit labels for an issue. """ try: labels = proxy_request("put", "/{0}/labels".format(number), data=request.data) return (labels.content, labels.status_code, get_headers(labels)) except GitHubError as e: print("GitHubError: ", e.response.status_code) return (":(", e.response.status_code)
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/. """ rate_limit_uri = "https://api.github.com/rate_limit" request_headers = get_request_headers(g.request_headers) if g.user: rl = github.raw_request("GET", "rate_limit", headers=request_headers) else: rl = proxy_request("get", uri=rate_limit_uri, headers=request_headers) return rl.content
def proxy_issue(number): '''XHR endpoint to get issue data from GitHub. either as an authed user, or as one of our proxy bots. ''' request_headers = get_request_headers(g.request_headers) if g.user: issue = github.raw_request('GET', 'repos/{0}/{1}'.format(ISSUES_PATH, number), headers=request_headers) else: issue = proxy_request('get', '/{0}'.format(number), headers=request_headers) return (issue.content, issue.status_code, get_headers(issue))
def modify_labels(number): '''XHR endpoint to modify issue labels. Sending in an empty array removes them all as well. This method is always proxied because non-repo collabs can't normally edit labels for an issue. ''' try: labels = proxy_request('put', '/{0}/labels'.format(number), data=request.data) return (labels.content, labels.status_code, get_headers(labels)) except GitHubError as e: print('GitHubError: ', e.response.status_code) return (':(', e.response.status_code)
def get_untriaged(): '''Return all issues that are "untriaged". Essentially all unclosed issues with no activity. Cached for 5 minutes. ''' if g.user: issues = github.raw_request('GET', 'repos/{0}'.format(REPO_URI)) else: issues = proxy_request('get') # Do not send random JSON to filter_untriaged if issues.status_code == 200: return (filter_untriaged(json.loads(issues.content)), issues.status_code, get_headers(issues)) else: return ({}, issues.status_code, get_headers(issues))
def proxy_issue(number): '''XHR endpoint to get issue data from GitHub. either as an authed user, or as one of our proxy bots. ''' request_headers = get_request_headers(g.request_headers) if g.user: issue = github.raw_request('GET', 'repos/{0}/{1}'.format( ISSUES_PATH, number), headers=request_headers) else: issue = proxy_request('get', '/{0}'.format(number), headers=request_headers) if issue.status_code != 404: return (issue.content, issue.status_code, get_headers(issue)) else: # We may want in the future handle 500 type of errors. # This will return the JSON version of 404 abort(404)
def proxy_issues(): """API endpoint to list all issues from GitHub.""" 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) if g.user: issues = github.raw_request("GET", "repos/{0}".format(ISSUES_PATH), params=params) else: issues = proxy_request("get", params=params) return (issues.content, issues.status_code, get_headers(issues))
def proxy_issues(): '''API endpoint to list all issues from GitHub.''' 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) if g.user: issues = github.raw_request('GET', 'repos/{0}'.format(ISSUES_PATH), params=params) else: issues = proxy_request('get', params=params) return (issues.content, issues.status_code, get_headers(issues))
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. Not cached. ''' params = params or request.args.copy() query_string = query_string or params.get('q') search_uri = 'https://api.github.com/search/issues' # 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) request_headers = get_request_headers(g.request_headers) if g.user: results = github.raw_request('GET', 'search/issues', params=params, headers=request_headers) else: results = proxy_request('get', params=params, uri=search_uri, headers=request_headers) return (results.content, results.status_code, get_headers(results))