From 197659c0201303d8ed5d5028d6de99676b85ba69 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Fri, 31 Jul 2015 09:37:30 -0600 Subject: [PATCH] Add initial jira integration that gets summary data We pull the credentials from a config file and use them to get information out of jira about created tickets, completed tickets and tickets without an epic --- bin/jira-summary | 46 +++++++++++++++++++++++++++++++++++ teamanalysis/config.py | 9 +++++++ teamanalysis/jira.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100755 bin/jira-summary create mode 100644 teamanalysis/config.py create mode 100644 teamanalysis/jira.py diff --git a/bin/jira-summary b/bin/jira-summary new file mode 100755 index 0000000..c55f60d --- /dev/null +++ b/bin/jira-summary @@ -0,0 +1,46 @@ +#!/usr/bin/env python +import datetime +import logging +import pprint +import requests +import teamanalysis.config +import teamanalysis.jira +import teamanalysis.time + +LOGGER = logging.getLogger('jira-summary') + +def _get_without_epic(created): + without_epic = [issue for issue in created['issues'] if issue['fields']['customfield_10008'] is None] + return without_epic + +def _show_summary(session, timepoint): + start, end = teamanalysis.time.get_checkpoint(timepoint) + created = teamanalysis.jira.issues_created_between(session, start, end) + without_epic = _get_without_epic(created) + resolved = teamanalysis.jira.issues_resolved_between(session, start, end) + print("\t".join([ + start.date().isoformat(), + end.date().isoformat(), + str(created['total']), + str(resolved['total']), + str(len(without_epic)), + ])) + +def main(): + logging.basicConfig() + logging.getLogger().setLevel(logging.DEBUG) + logging.getLogger('requests').setLevel(logging.INFO) + + config = teamanalysis.config.get() + + timepoint = datetime.datetime(2015, 5, 1, 0, 0, 1) + session = teamanalysis.jira.create_session(**config['jira']) + + now = datetime.datetime.utcnow() + while timepoint < now + datetime.timedelta(days=7): + _show_summary(session, timepoint) + timepoint = timepoint + datetime.timedelta(days=7) + + +if __name__ == '__main__': + main() diff --git a/teamanalysis/config.py b/teamanalysis/config.py new file mode 100644 index 0000000..44b6310 --- /dev/null +++ b/teamanalysis/config.py @@ -0,0 +1,9 @@ +import json +import os + +def get(): + home = os.environ['HOME'] + path = os.path.join(home, '.teamanalysis') + with open(path, 'r') as f: + data = json.load(f) + return data diff --git a/teamanalysis/jira.py b/teamanalysis/jira.py new file mode 100644 index 0000000..f4976aa --- /dev/null +++ b/teamanalysis/jira.py @@ -0,0 +1,54 @@ +import logging +import requests +import requests.auth + +LOGGER = logging.getLogger(__name__) + +def create_session(username, password): + auth = requests.auth.HTTPBasicAuth(username, password) + session = requests.Session() + session.auth = auth + return session + +def _do_search(session, payload, startAt=None): + startAt = startAt if startAt is not None else 0 + payload['startAt'] = startAt + response = session.post("https://sendshapes.atlassian.net/rest/api/2/search", json=payload) + if not response.ok: + import pdb;pdb.set_trace() + raise Exception("Failed to query jira: {}".format(response.json())) + data = response.json() + return data + +def search(session, payload): + startAt = 0 + data = _do_search(session, payload, startAt) + results = data + while results['total'] > results['maxResults']: + startAt += data['maxResults'] + data = _do_search(session, payload, startAt) + results['maxResults'] += data['maxResults'] + results['issues'] += data['issues'] + return results + +def get_issue(session, issue): + query = { + "jql" :"id = {}".format(issue), + } + return search(session, query) + +def issues_created_between(session, start, end): + jql = "created >= {} AND created < {}".format(start.date().isoformat(), end.date().isoformat()) + query = { + "jql" : jql, + "fields" : ["id", "created", "customfield_10008"], + } + return search(session, query) + +def issues_resolved_between(session, start, end): + jql = "resolved >= {} AND resolved < {}".format(start.date().isoformat(), end.date().isoformat()) + query = { + "jql" : jql, + "fields" : ["id", "resolved"], + } + return search(session, query)