Beispiel #1
0
def add_user_transitions_to_issues(issues, user_transitions):
    all_from_statuses = [ user_transition.split(',')[0].lower() for user_transition in user_transitions.values() ]
    all_to_statuses = [ user_transition.split(',')[1].lower() for user_transition in user_transitions.values() ]

    for issue in issues:
        from_status_times = {}
        to_status_times = {}
        # Register only the first change to from status and always the last change to to status
        for transition in issue['__transitions']:
            status = '+' + transition['to_status'].lower().replace(' ', '')
            if not status in from_status_times and status in all_from_statuses:
                from_status_times[status] = transition['when']
            if status in all_to_statuses:
                to_status_times[status] = transition['when']

            if transition['from_status']:
                status = '-' + transition['from_status'].lower().replace(' ', '')
                if not status in from_status_times and status in all_from_statuses:
                    from_status_times[status] = transition['when']
                if status in all_to_statuses:
                    to_status_times[status] = transition['when']

        result = {}
        for user_transition_key, user_transition_value in user_transitions.items():
            from_status = user_transition_value.split(',')[0].lower()
            to_status = user_transition_value.split(',')[1].lower()
            result[user_transition_key] = (parse_iso(to_status_times[to_status]) - parse_iso(from_status_times[from_status])).total_seconds() / (24 * 3600) if (from_status in from_status_times) and (to_status in to_status_times) else 'NA'
            from_status_field_name = 'first_time_' + ('into_' if from_status[0] == '+' else 'out_of_') + from_status[1:]
            to_status_field_name = 'last_time_' + ('into_' if to_status[0] == '+' else 'out_of_') + to_status[1:]
            result[from_status_field_name] = from_status_times[from_status] if from_status in from_status_times else 'NA'
            result[to_status_field_name] = to_status_times[to_status] if to_status in to_status_times else 'NA'

        issue['__user_transitions'] = result
Beispiel #2
0
def write_issue_counts(basename, dir, issues):
    if len(issues) == 0:
        return

    with open(os.path.join(dir, basename + '-daycounts.csv'), 'w') as csv_file:
        writer = util.Utf8CsvDictWriter(csv_file, ['day', 'status', 'count'])

        #TODO: prettify garble, probably want to create a generator for the days
        transitions, known_statuses = all_transitions_and_known_statuses(
            issues)

        issue_counts = {s: 0 for s in known_statuses}

        one_day = datetime.timedelta(days=1)
        day = parse_iso(transitions[0]['when'])
        itr = iter(transitions)
        line = itr.next()
        while day <= parse_iso(transitions[-1]['when']):
            while parse_iso(line['when']) < day:
                issue_counts[line['from_status']] -= 1
                issue_counts[line['to_status']] += 1
                line = itr.next()

            rows = [{
                'day': day.isoformat(),
                'status': k,
                'count': v
            } for k, v in issue_counts.items() if k != None]
            for row in rows:
                writer.writerow(row)

            day += one_day
Beispiel #3
0
def write_issue_counts(basename, dir, issues):
    if len(issues) == 0:
        return

    with open(os.path.join(dir, basename + '-daycounts.csv'), 'w') as csv_file:
        writer = util.Utf8CsvDictWriter(csv_file, ['day', 'status', 'count'])

        #TODO: prettify garble, probably want to create a generator for the days
        transitions, known_statuses = all_transitions_and_known_statuses(issues)

        issue_counts = { s : 0 for s in known_statuses }

        one_day = datetime.timedelta(days = 1)
        day = parse_iso(transitions[0]['when'])
        itr = iter(transitions)
        line = itr.next()
        while day <= parse_iso(transitions[-1]['when']):
            while parse_iso(line['when']) < day:
                issue_counts[line['from_status']] -= 1
                issue_counts[line['to_status']] += 1
                line = itr.next()

            rows = [
                {
                    'day' : day.isoformat(),
                    'status' : k,
                    'count' : v
                } for k,v in issue_counts.items() if k != None ]
            for row in rows:
                writer.writerow(row)

            day += one_day
Beispiel #4
0
def add_transitions_to_issues(issues):
    for issue in issues:
        # filter histories for changes that involve the status field
        log = issue['changelog']['histories']
        workflow_log = [
            line for line in log
            if 'status' in [i['field'] for i in line['items']]
        ]

        #remove non status related items from log
        for line in workflow_log:
            line['status_item'], = filter(lambda i: i['field'] == 'status',
                                          line['items'])

        # Not sure if they come in sorted order
        workflow_log.sort(key=lambda x: x['created'])

        # Create a list from the from 'nothing' to Open transition and the rest of the transitions
        transitions = [
            {
                'transition': 'Non-existent to Open',
                'when': retrieve_dotnotation_field(issue, 'fields.created'),
                'who': retrieve_dotnotation_field(issue,
                                                  'fields.reporter.name'),
                'from_status': None,
                'to_status': 'Open',
                'days_in_from_status': None,
                'days_since_open': None
            }
        ] + [{
            'transition':
            '%s to %s' %
            (retrieve_dotnotation_field(line, 'status_item.fromString'),
             retrieve_dotnotation_field(line, 'status_item.toString')),
            'when':
            retrieve_dotnotation_field(line, 'created'),
            'who':
            retrieve_dotnotation_field(line, 'author.name'),
            'from_status':
            retrieve_dotnotation_field(line, 'status_item.fromString'),
            'to_status':
            retrieve_dotnotation_field(line, 'status_item.toString'),
            'days_since_open':
            (parse_iso(retrieve_dotnotation_field(line, 'created')) -
             parse_iso(retrieve_dotnotation_field(
                 issue, 'fields.created'))).total_seconds() / (24 * 3600)
        } for line in workflow_log]

        # Calculate days between transitions
        for idx in xrange(1, len(transitions)):
            transitions[idx]['days_in_from_status'] = (
                parse_iso(transitions[idx]['when']) -
                parse_iso(transitions[idx - 1]['when'])).total_seconds() / (
                    24 * 3600)

        issue['__transitions'] = transitions
Beispiel #5
0
def add_user_transitions_to_issues(issues, user_transitions):
    all_from_statuses = [
        user_transition.split(',')[0].lower()
        for user_transition in user_transitions.values()
    ]
    all_to_statuses = [
        user_transition.split(',')[1].lower()
        for user_transition in user_transitions.values()
    ]

    for issue in issues:
        from_status_times = {}
        to_status_times = {}
        # Register only the first change to from status and always the last change to to status
        for transition in issue['__transitions']:
            status = '+' + transition['to_status'].lower().replace(' ', '')
            if not status in from_status_times and status in all_from_statuses:
                from_status_times[status] = transition['when']
            if status in all_to_statuses:
                to_status_times[status] = transition['when']

            if transition['from_status']:
                status = '-' + transition['from_status'].lower().replace(
                    ' ', '')
                if not status in from_status_times and status in all_from_statuses:
                    from_status_times[status] = transition['when']
                if status in all_to_statuses:
                    to_status_times[status] = transition['when']

        result = {}
        for user_transition_key, user_transition_value in user_transitions.items(
        ):
            from_status = user_transition_value.split(',')[0].lower()
            to_status = user_transition_value.split(',')[1].lower()
            result[user_transition_key] = (
                parse_iso(to_status_times[to_status]) -
                parse_iso(from_status_times[from_status])).total_seconds() / (
                    24 * 3600) if (from_status in from_status_times) and (
                        to_status in to_status_times) else 'NA'
            from_status_field_name = 'first_time_' + (
                'into_'
                if from_status[0] == '+' else 'out_of_') + from_status[1:]
            to_status_field_name = 'last_time_' + (
                'into_' if to_status[0] == '+' else 'out_of_') + to_status[1:]
            result[from_status_field_name] = from_status_times[
                from_status] if from_status in from_status_times else 'NA'
            result[to_status_field_name] = to_status_times[
                to_status] if to_status in to_status_times else 'NA'

        issue['__user_transitions'] = result
Beispiel #6
0
def add_transitions_to_issues(issues):
    for issue in issues:
        # filter histories for changes that involve the status field
        log = issue['changelog']['histories']
        workflow_log = [ line for line in log if 'status' in [i['field'] for i in line['items']] ]

        #remove non status related items from log
        for line in workflow_log:
            line['status_item'], = filter(lambda i: i['field'] == 'status', line['items'])

        # Not sure if they come in sorted order
        workflow_log.sort(key = lambda x: x['created'])

        # Create a list from the from 'nothing' to Open transition and the rest of the transitions
        transitions = [{
            'transition' : 'Non-existent to Open',
            'when' : retrieve_dotnotation_field(issue, 'fields.created'),
            'who' : retrieve_dotnotation_field(issue, 'fields.reporter.name'),
            'from_status' : None,
            'to_status' : 'Open',
            'days_in_from_status' : None,
            'days_since_open' : None
        }] + [{
            'transition' : '%s to %s' % (retrieve_dotnotation_field(line, 'status_item.fromString'), retrieve_dotnotation_field(line, 'status_item.toString')),
            'when' : retrieve_dotnotation_field(line, 'created'),
            'who' : retrieve_dotnotation_field(line, 'author.name'),
            'from_status' : retrieve_dotnotation_field(line, 'status_item.fromString'),
            'to_status' : retrieve_dotnotation_field(line, 'status_item.toString'),
            'days_since_open' : (parse_iso(retrieve_dotnotation_field(line, 'created')) - parse_iso(retrieve_dotnotation_field(issue, 'fields.created'))).total_seconds() / (24 * 3600)
        } for line in workflow_log]

        # Calculate days between transitions
        for idx in xrange(1, len(transitions)):
            transitions[idx]['days_in_from_status'] = (parse_iso(transitions[idx]['when']) - parse_iso(transitions[idx - 1]['when'])).total_seconds() / (24 * 3600)

        issue['__transitions'] = transitions
Beispiel #7
0
def issue_fields(issue):
    result = {}

    # Add basic fields
    for field_name, dotted_field in as_is_fields.items():
        result[field_name] = retrieve_dotnotation_field(issue, dotted_field)

    # Add user transitions
    for field_name, field_value in issue['__user_transitions'].items():
        result[field_name] = field_value

    # Calculate # of days in current status
    result['days_in_current_status'] = (datetime.datetime.now(iso8601.Utc()) - parse_iso(issue['__transitions'][-1]['when'])).total_seconds() / (24 * 3600)

    # Add character lenghts for some fields
    description_field = retrieve_dotnotation_field(issue, 'fields.description')
    summary_field = retrieve_dotnotation_field(issue, 'fields.summary')
    result['description_length'] = len(description_field) if description_field else None
    result['summary_length'] = len(summary_field) if summary_field else None

    return result
Beispiel #8
0
def issue_fields(issue):
    result = {}

    # Add basic fields
    for field_name, dotted_field in as_is_fields.items():
        result[field_name] = retrieve_dotnotation_field(issue, dotted_field)

    # Add user transitions
    for field_name, field_value in issue['__user_transitions'].items():
        result[field_name] = field_value

    # Calculate # of days in current status
    result['days_in_current_status'] = (
        datetime.datetime.now(iso8601.Utc()) - parse_iso(
            issue['__transitions'][-1]['when'])).total_seconds() / (24 * 3600)

    # Add character lenghts for some fields
    description_field = retrieve_dotnotation_field(issue, 'fields.description')
    summary_field = retrieve_dotnotation_field(issue, 'fields.summary')
    result['description_length'] = len(
        description_field) if description_field else None
    result['summary_length'] = len(summary_field) if summary_field else None

    return result
Beispiel #9
0
def most_recent_update(issues):
    return parse_iso(max(i['fields']['updated'] for i in issues))
Beispiel #10
0
def most_recent_update(issues):
    return parse_iso(max(i['fields']['updated'] for i in issues))