Created
July 5, 2021 09:38
-
-
Save lelegard/0fc71aa3181f6f14d5086d04b7ff305d to your computer and use it in GitHub Desktop.
Analyze all contributions in the issues area of a GitHub repository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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