| Sivas SRR | a464a7c | 2017-02-19 23:35:59 -0600 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 2 |  | 
|  | 3 | r""" | 
|  | 4 | Exports issues from a list of repositories to individual CSV files. | 
|  | 5 | Uses basic authentication (GitHub username + password) to retrieve issues | 
|  | 6 | from a repository that username has access to. Supports GitHub API v3. | 
|  | 7 | """ | 
|  | 8 | import argparse | 
|  | 9 | import csv | 
|  | 10 | from getpass import getpass | 
|  | 11 | import requests | 
|  | 12 |  | 
|  | 13 | auth = None | 
|  | 14 | states = 'all' | 
|  | 15 |  | 
|  | 16 |  | 
|  | 17 | def write_issues(response, csv_out): | 
|  | 18 | r""" | 
|  | 19 | Parses JSON response and writes to CSV. | 
|  | 20 | """ | 
|  | 21 | print response | 
|  | 22 | if response.status_code != 200: | 
|  | 23 | raise Exception(response.status_code) | 
|  | 24 | for issue in response.json(): | 
|  | 25 | if 'pull_request' not in issue: | 
|  | 26 | labels = ', '.join([l['name'] for l in issue['labels']]) | 
|  | 27 | date = issue['created_at'].split('T')[0] | 
|  | 28 | # Change the following line to write out additional fields | 
|  | 29 | csv_out.writerow([labels.encode('utf-8'), | 
|  | 30 | issue['title'].encode('utf-8'), | 
|  | 31 | issue['state'].encode('utf-8'), | 
|  | 32 | date.encode('utf-8'), | 
|  | 33 | issue['html_url'].encode('utf-8'), | 
|  | 34 | issue['user']['login'].encode('utf-8')]) | 
|  | 35 |  | 
|  | 36 |  | 
|  | 37 | def get_github_issues(name): | 
|  | 38 | r""" | 
|  | 39 | Requests issues from GitHub API and writes to CSV file. | 
|  | 40 | """ | 
|  | 41 | print name | 
|  | 42 | print states | 
|  | 43 | l_url = 'https://api.github.com/repos/{}/issues?state={}'.format(name, | 
|  | 44 | states) | 
|  | 45 | print l_url | 
|  | 46 | # 'https://api.github.com/repos/{}/issues?state={}'.format(name, state) | 
|  | 47 | response = requests.get(l_url, auth=auth) | 
|  | 48 |  | 
|  | 49 | csvfilename = '{}-issues.csv'.format(name.replace('/', '-')) | 
|  | 50 | with open(csvfilename, 'w') as csvfile: | 
|  | 51 | csv_out = csv.writer(csvfile) | 
|  | 52 | csv_out.writerow(['Labels', 'Title', 'State', 'Date', 'URL', 'Author']) | 
|  | 53 | write_issues(response, csv_out) | 
|  | 54 |  | 
|  | 55 | # Multiple requests are required if response is paged | 
|  | 56 | if 'link' in response.headers: | 
|  | 57 | pages = {rel[6:-1]: url[url.index('<')+1:-1] for url, rel in | 
|  | 58 | (link.split(';') for link in | 
|  | 59 | response.headers['link'].split(','))} | 
|  | 60 | while 'last' in pages and 'next' in pages: | 
|  | 61 | pages = {rel[6:-1]: url[url.index('<')+1:-1] for url, rel in | 
|  | 62 | (link.split(';') for link in | 
|  | 63 | response.headers['link'].split(','))} | 
|  | 64 | response = requests.get(pages['next'], auth=auth) | 
|  | 65 | write_issues(response, csv_out) | 
|  | 66 | if pages['next'] == pages['last']: | 
|  | 67 | break | 
|  | 68 |  | 
|  | 69 | csvfile.close() | 
|  | 70 |  | 
|  | 71 | parser = argparse.ArgumentParser(description="Write GitHub repository issues " | 
|  | 72 | "to CSV file.") | 
|  | 73 |  | 
|  | 74 | parser.add_argument('username', nargs='+', help="GitHub user name, " | 
|  | 75 | "formatted as 'username'") | 
|  | 76 |  | 
|  | 77 | parser.add_argument('password', nargs='+', help="GitHub username password, " | 
|  | 78 | "formatted as 'password'") | 
|  | 79 |  | 
|  | 80 | parser.add_argument('repositories', nargs='+', help="Repository names, " | 
|  | 81 | "formatted as 'basereponame/repo'") | 
|  | 82 |  | 
|  | 83 | parser.add_argument('--all', action='store_true', help="Returns both open " | 
|  | 84 | "and closed issues.") | 
|  | 85 | args = parser.parse_args() | 
|  | 86 |  | 
|  | 87 | if args.all: | 
|  | 88 | state = 'all' | 
|  | 89 |  | 
|  | 90 | for argusername in args.username: | 
|  | 91 | username = argusername | 
|  | 92 |  | 
|  | 93 | for argpassword in args.password: | 
|  | 94 | password = argpassword | 
|  | 95 |  | 
|  | 96 | auth = (username, password) | 
|  | 97 |  | 
|  | 98 | for repository in args.repositories: | 
|  | 99 | get_github_issues(repository) |