system-config/tools/atc/email-stats.py
James E. Blair 96f2f6ddd9 Initial checkin of ATC scripts
Change-Id: Ibffab01bc835d380ca9f0c18521c8a6d808de761
2013-09-24 09:34:10 -07:00

142 lines
4.2 KiB
Python
Executable File

#!/usr/bin/python
# Copyright (C) 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Soren Hansen wrote the original version of this script.
# James Blair hacked it up to include email addresses from gerrit.
import calendar
import datetime
import json
import optparse
import paramiko
from pprint import pprint
import sys
import csv
import re
MAILTO_RE = re.compile('mailto:(.*)')
USERNAME_RE = re.compile('username:(.*)')
accounts = {}
class Account(object):
def __init__(self, num):
self.num = num
self.full_name = ''
self.emails = []
self.username = None
def get_account(num):
a = accounts.get(num)
if not a:
a = Account(num)
accounts[num] = a
return a
for row in csv.reader(open('emails.csv')):
num, email, pw, external = row
num = int(num)
a = get_account(num)
if email and email != '\\N' and email not in a.emails:
a.emails.append(email)
m = MAILTO_RE.match(external)
if m:
if m.group(1) not in a.emails:
a.emails.append(m.group(1))
m = USERNAME_RE.match(external)
if m:
if a.username:
print a.num
print a.username
raise Exception("Already a username")
a.username = m.group(1)
for row in csv.reader(open('accounts.csv')):
num = int(row[-1])
name = row[1]
a = get_account(num)
a.full_name = name
username_accounts = {}
for a in accounts.values():
username_accounts[a.username] = a
atcs = []
optparser = optparse.OptionParser()
optparser.add_option('-p', '--project', default='nova', help='Project to generate stats for')
optparser.add_option('-o', '--output', default='out.csv', help='Output file')
options, args = optparser.parse_args()
QUERY = "project:%s status:merged" % options.project
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.load_system_host_keys()
client.connect('review.openstack.org', port=29418, key_filename='/home/corvus/.ssh/id_rsa', username='CHANGME')
stdin, stdout, stderr = client.exec_command('gerrit query %s --all-approvals --format JSON' %
QUERY)
changes = []
done = False
last_sortkey = ''
tz = datetime.tzinfo
start_date = datetime.datetime(2012, 9, 27, 0, 0, 0)
end_date = datetime.datetime(2013, 7, 30, 0, 0, 0)
count = 0
earliest = datetime.datetime.now()
while not done:
for l in stdout:
data = json.loads(l)
if 'rowCount' in data:
if data['rowCount'] < 500:
done = True
continue
count += 1
last_sortkey = data['sortKey']
if 'owner' not in data:
continue
if 'username' not in data['owner']:
continue
account = username_accounts[data['owner']['username']]
approved = False
for ps in data['patchSets']:
if 'approvals' not in ps:
continue
for aprv in ps['approvals']:
if aprv['type'] != 'SUBM':
continue
ts = datetime.datetime.fromtimestamp(aprv['grantedOn'])
if ts < start_date or ts > end_date:
continue
approved = True
if ts < earliest:
earliest = ts
if approved and account not in atcs:
atcs.append(account)
if not done:
stdin, stdout, stderr = client.exec_command('gerrit query %s resume_sortkey:%s --all-approvals --format JSON' % (QUERY, last_sortkey))
print 'project: %s' % options.project
print 'examined %s changes' % count
print 'earliest timestamp: %s' % earliest
writer = csv.writer(open(options.output, 'w'))
for a in atcs:
writer.writerow([a.username, a.full_name] + a.emails)
print