Example #1
0
    def __init__(self):
        """
        Report initialization that uses reports.conf file.

        """
        config = self._get_config()
        date_format = '%Y/%m/%d'

        self.sprints = tuple(config.get('sprints', '').strip().split(','))
        self.date_from = datetime.datetime.strptime(config['date_from'], date_format)
        self.date_to = datetime.datetime.strptime(config['date_to'], date_format)
        self.usernames = tuple(config['usernames'].strip().split(','))
        self.projects = tuple(config.get('projects', '').strip().split(','))
        self.issue_types = tuple(config.get('issue_types', '').strip().split(','))
        self.status = tuple(config.get('status', '').strip().split(','))

        # Jira Client
        self.client = JiraClient()

        # Custom fields
        self.custom_fields = self.client.custom_fields
Example #2
0
class JiraReport(object):
    def __init__(self):
        """
        Report initialization that uses reports.conf file.

        """
        config = self._get_config()
        date_format = '%Y/%m/%d'

        self.sprints = tuple(config.get('sprints', '').strip().split(','))
        self.date_from = datetime.datetime.strptime(config['date_from'], date_format)
        self.date_to = datetime.datetime.strptime(config['date_to'], date_format)
        self.usernames = tuple(config['usernames'].strip().split(','))
        self.projects = tuple(config.get('projects', '').strip().split(','))
        self.issue_types = tuple(config.get('issue_types', '').strip().split(','))
        self.status = tuple(config.get('status', '').strip().split(','))

        # Jira Client
        self.client = JiraClient()

        # Custom fields
        self.custom_fields = self.client.custom_fields

    def _get_config(self) -> Dict[str, str]:
        """
        Gets config parameters.
        File: reports.conf

        :return: Config parameters.
        """
        parser = ConfigParser()
        parser.read(os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'reports.conf')))

        # Get jira arguments
        try:
            jira = {option: parser.get('jira', option) for option in parser.options('jira')}
        except Exception as e:
            raise ImproperlyConfigured('jira') from e

        return jira

    def resolution_tasks(self) -> pd.DataFrame:
        """
        Report all tasks given their resolution date. The fields included are:
        - Key.
        - Assignee.
        - Summary.
        - T-Shirt.
        - Story Points.
        - Original Estimate.
        - Time Spent.
        - Type.
        - Project.

        :return: Tasks.
        """

        def get_tasks_data(issue):
            fields = issue['fields']
            t_shirt = fields.get(self.custom_fields['t_shirt_size'], {}) or {}

            return {
                'Key': issue['key'],
                'Assignee': fields['assignee']['displayName'] if fields['assignee'] else None,
                'Summary': fields['summary'],
                'Type': fields['issuetype']['name'],
                'T-Shirt': t_shirt.get('value', None),
                'Story Points': fields.get(self.custom_fields['story_points'], None),
                'Original Estimate': fields['aggregatetimeoriginalestimate'] / 3600 if fields[
                    'aggregatetimeoriginalestimate'] else 0,
                'Time Spent': fields['aggregatetimespent'] / 3600 if fields['aggregatetimespent'] else 0,
                'Project': fields['project']['name'],
            }

        # Create list of fields to retrieve
        included_fields = (
            'key',
            'assignee',
            'summary',
            self.custom_fields['story_points'],
            self.custom_fields['t_shirt_size'],
            'aggregatetimeoriginalestimate',
            'aggregatetimespent',
            'issuetype',
            'project'
        )

        # Get tasks from client
        tasks = self.client.get_resolution_tasks(
            projects=self.projects,
            issue_types=self.issue_types,
            status=self.status,
            date_from=self.date_from.strftime("%Y/%m/%d"),
            date_to=self.date_to.strftime("%Y/%m/%d"),
            get_data=get_tasks_data,
            fields=included_fields,
        )

        return pd.DataFrame.from_records(tasks, index='Key')

    def sprint_tasks(self) -> pd.DataFrame:
        """
        Report all tasks of a sprint. The fields included are:
        - Key.
        - Assignee.
        - Summary.
        - T-Shirt.
        - Story Points.
        - Original Estimate.
        - Time Spent.
        - Type.
        - Project.

        :return: Tasks.
        """

        def get_tasks_data(issue):
            fields = issue['fields']
            t_shirt = fields.get(self.custom_fields['t_shirt_size'], {}) or {}

            return {
                'Key': issue['key'],
                'Assignee': fields['assignee']['displayName'] if fields['assignee'] else None,
                'Summary': fields['summary'],
                'Type': fields['issuetype']['name'],
                'T-Shirt': t_shirt.get('value', None),
                'Story Points': fields.get(self.custom_fields['story_points'], None),
                'Original Estimate': fields['aggregatetimeoriginalestimate'] / 3600 if fields[
                    'aggregatetimeoriginalestimate'] else 0,
                'Time Spent': fields['aggregatetimespent'] / 3600 if fields['aggregatetimespent'] else 0,
                'Project': fields['project']['name'],
            }

        # Create list of fields to retrieve
        included_fields = (
            'key',
            'assignee',
            'summary',
            self.custom_fields['story_points'],
            self.custom_fields['t_shirt_size'],
            'aggregatetimeoriginalestimate',
            'aggregatetimespent',
            'issuetype',
            'project'
        )

        # Get tasks from client
        tasks = self.client.get_sprint_tasks(
            get_data=get_tasks_data,
            projects=self.projects,
            sprints=self.sprints,
            fields=included_fields
        )

        return pd.DataFrame.from_records(tasks, index='Key')

    def sprint_subtasks(self) -> Dict[str, Any]:
        """
        Report all subtasks of a sprint. The fields included are:

        :return: Subtasks.
        """

        def get_subtasks_data(issue):
            fields = issue['fields']
            resolution = fields.get('resolution', {}) or {}

            return {
                'Key': issue['key'],
                'Parent': fields['parent']['key'],
                'Summary': fields['summary'],
                'Type': fields['issuetype']['name'],
                'Status': fields['status']['name'],
                'Resolution': resolution.get('name', None),
                'Original Estimate': fields['aggregatetimeoriginalestimate'] / 3600 if fields[
                    'aggregatetimeoriginalestimate'] else 0,
                'Time Spent': fields['aggregatetimespent'] / 3600 if fields['aggregatetimespent'] else 0,
                'Assignee': fields['assignee']['displayName'] if fields['assignee'] else None,
            }

        subtasks = self.client.get_sprint_subtasks(projects=self.projects, sprints=self.sprints)
        subtasks_data = [get_subtasks_data(subtask) for subtask in subtasks]
        return pd.DataFrame.from_records(subtasks_data, index='Key')

    def worklogs(self) -> pd.DataFrame:
        """
        Report all worklogs for a given user.

        :return: Worklogs.
        """

        def get_worklogs_data(worklog):
            return {
                'Author': worklog['author']['displayName'],
                'Key': worklog['issue']['key'],
                'Issue': worklog['issue']['summary'],
                'Type': worklog['issue']['issueType']['name'],
                'Time Spent': worklog['timeSpentSeconds'] / 3600,
                'Comment': worklog['comment'],
            }

        worklogs = [w for u in self.usernames for w in self.client.get_worklogs(self.date_from, self.date_to, u)]
        worklogs_data = [get_worklogs_data(worklog) for worklog in worklogs]
        return pd.DataFrame.from_records(worklogs_data)