Skip to content

Instantly share code, notes, and snippets.

@lelegard
Created July 5, 2021 09:38
Show Gist options
  • Save lelegard/0fc71aa3181f6f14d5086d04b7ff305d to your computer and use it in GitHub Desktop.
Save lelegard/0fc71aa3181f6f14d5086d04b7ff305d to your computer and use it in GitHub Desktop.
Analyze all contributions in the issues area of a GitHub repository
#!/usr/bin/env python
#
# Analyze all contributions in the issues area of a GitHub repository.
# Output a summary of all users and their contributions (issues, pull requests and comments).
# The summary is sorted in decreasing order of number of contributions.
#
import requests # pip install requests, see https://docs.python-requests.org/
# TO BE COMPLETED: fill with the right values for your repo
gh_owner = '...' # GitHub repository owner or organization
gh_repo = '...' # GitHub repository name
gh_user = '...' # GitHub user name for authenticated access to GitHub API (optional)
gh_token = '...' # GitHub personal access token for above user
# Get a paginated GitHub API output as one single big list.
def gh_get_paginated(url, params = {}):
result = []
params['per_page'] = '100'
while not url is None:
resp = requests.get(url,
params = params,
headers = {'Accept': 'application/vnd.github.v3+json'},
auth = (gh_user, gh_token))
result.extend(resp.json())
url = resp.links['next']['url'] if ('next' in resp.links and 'url' in resp.links['next']) else None
params = None
return result
# User context:
class user_context:
def __init__(self, name):
self.name = name
self.issues = 0
self.prs = 0
self.comments = 0
self.characters = 0
def total(self):
return self.issues + self.prs + self.comments
def __lt__(self, other):
return self.total() < other.total()
def __str__(self):
return '%-20s %8d %8d %8d %8d %8d' % (self.name, self.issues, self.prs, self.comments, self.total(), self.characters)
header = '%-20s %8s %8s %8s %8s %8s' % ('User name', 'Issues', 'PR', 'Comments', 'Total', 'Size')
# A dictionary of all users
users = {}
# Total of all users in one single instance.
total = user_context('Total')
# Get all issues and all comments.
base_url = 'https://api.github.com/repos/' + gh_owner + '/' + gh_repo
issues = gh_get_paginated(base_url + '/issues', {'state': 'all'})
comments = gh_get_paginated(base_url + '/issues/comments', {'state': 'all'})
# Analyze all issues.
for item in issues:
if 'user' in item and 'login' in item['user']:
user_name = item['user']['login']
if not user_name in users:
users[user_name] = user_context(user_name)
if 'pull_request' in item:
users[user_name].prs += 1
total.prs += 1
else:
users[user_name].issues += 1
total.issues += 1
if 'body' in item:
size = len(item['body'])
users[user_name].characters += size
total.characters += size
# Analyze all comments
for item in comments:
if 'user' in item and 'login' in item['user']:
user_name = item['user']['login']
if not user_name in users:
users[user_name] = user_context(user_name)
users[user_name].comments += 1
total.comments += 1
if 'body' in item:
size = len(item['body'])
users[user_name].characters += size
total.characters += size
# Print final summary
total.name += ' (%d users)' % len(users)
print(user_context.header)
print(str(total))
for user in sorted(users.values(), reverse = True):
print(str(user))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment