Skip to content

Instantly share code, notes, and snippets.

@seize-the-dave
Last active June 13, 2017 22:11
Show Gist options
  • Save seize-the-dave/d12bc2f9778362a36576a4cb42b20db2 to your computer and use it in GitHub Desktop.
Save seize-the-dave/d12bc2f9778362a36576a4cb42b20db2 to your computer and use it in GitHub Desktop.
Flow Efficiency Calculation for JIRA
from jira import JIRA
import arrow
import datetime
from collections import defaultdict
jira = JIRA()
work = []
work.append('In Progress')
work.append('In Review')
work.append('In Definition')
work.append('Option Review')
done = []
done.append('Resolved')
done.append('Closed')
done.append('Done')
def log_change(log, state, curr_change, prev_change):
if state in done:
return prev_change
log[state] += curr_change - prev_change
return curr_change
def append_log(master_log, log):
for key in log.keys():
master_log[key] += log[key]
def wait_time(log):
delta = datetime.timedelta()
for state in log:
if state not in work:
delta += log[state]
return delta
def work_time(log):
delta = datetime.timedelta()
for state in log:
if state in work:
delta += log[state]
return delta
master_log = defaultdict(datetime.timedelta)
print('Individual Issues')
projects = ['PORT']
buffer_size = 200
start_at = 0
while (buffer_size > 0):
issues = jira.search_issues('project IN ("{}") AND type in (standardIssueTypes()) AND status in ({}) ORDER BY key ASC'.format('","'.join(projects),','.join(done)), maxResults=buffer_size, startAt=start_at, expand='changelog')
for issue in issues:
issue_log = defaultdict(datetime.timedelta)
prev_change = arrow.get(issue.fields.created)
changelog = issue.changelog
for history in changelog.histories:
for change in history.items:
if change.field != 'status':
continue
prev_change = log_change(issue_log, str(change.fromString), arrow.get(history.created), prev_change)
curr_status = str(issue.fields.status)
log_change(issue_log, curr_status, arrow.now(), prev_change)
issue_work_time = work_time(issue_log)
issue_wait_time = wait_time(issue_log)
issue_time = issue_work_time + issue_wait_time
print('{:s}: {:0.2f}% ({:s} / {:s}) {:s} [{:s}]'.format(str(issue.permalink()) , issue_work_time * 100 / (issue_time), str(issue_work_time), str(issue_time), curr_status, str(issue.fields.issuetype)))
append_log(master_log, issue_log)
if len(issues) < buffer_size:
buffer_size = 0
else:
start_at += buffer_size
total_work_time = work_time(master_log)
total_wait_time = wait_time(master_log)
total_time = total_work_time + total_wait_time
print()
print('Time in Status Summary')
for status in master_log.keys():
if master_log[status] != datetime.timedelta():
print('[{}] {}: {:0.2f}% ({:s} / {:s})'.format('WORK' if status in work else 'WAIT', status, master_log[status] * 100 / (total_time), str(master_log[status]), str(total_time)))
print()
print('Overall')
print('{:0.2f}% ({:s} / {:s})'.format(total_work_time * 100 / (total_time), str(total_work_time), str(total_time)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment