1#!/usr/bin/env python 2 3r""" 4Exports issues from a list of repositories to individual CSV files. 5Uses basic authentication (GitHub username + password) to retrieve issues 6from a repository that username has access to. Supports GitHub API v3. 7""" 8import argparse 9import csv 10from getpass import getpass 11import requests 12 13auth = None 14states = 'all' 15 16 17def 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 37def 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 71parser = argparse.ArgumentParser(description="Write GitHub repository issues " 72 "to CSV file.") 73 74parser.add_argument('username', nargs='+', help="GitHub user name, " 75 "formatted as 'username'") 76 77parser.add_argument('password', nargs='+', help="GitHub username password, " 78 "formatted as 'password'") 79 80parser.add_argument('repositories', nargs='+', help="Repository names, " 81 "formatted as 'basereponame/repo'") 82 83parser.add_argument('--all', action='store_true', help="Returns both open " 84 "and closed issues.") 85args = parser.parse_args() 86 87if args.all: 88 state = 'all' 89 90for argusername in args.username: 91 username = argusername 92 93for argpassword in args.password: 94 password = argpassword 95 96auth = (username, password) 97 98for repository in args.repositories: 99 get_github_issues(repository) 100