<commit_before># -- coding: utf-8 --
from __future__ import absolute_import

import re
import json
from os.path import join
from collections import Counter
from datetime import datetime
from . import constants, repo_functions

class ChimeActivity:
    ''' A representation of an activity in Chime
    '''
    def __init__(self, repo, branch_name, default_branch_name, actor_email):
        ''' Create a new activity.
        '''
        self.repo = repo
        self.safe_branch = branch_name
        self.default_branch_name = default_branch_name

        task_metadata = repo_functions.get_task_metadata_for_branch(self.repo, self.safe_branch)
        self.author_email, self.task_description = self._process_task_metadata(task_metadata)

        self.review_state, self.review_authorized = repo_functions.get_review_state_and_authorized(
            repo=self.repo, default_branch_name=self.default_branch_name,
            working_branch_name=self.safe_branch, actor_email=actor_email
        )

        self.date_created = self.repo.git.log(self.safe_branch, '--format=%ad', '--date=relative', '--', repo_functions.TASK_METADATA_FILENAME).split('\n')[-1]
        self.date_updated = self.repo.git.log(self.safe_branch, '-1', '--format=%ad', '--date=relative')

        # the email of the last person who edited the activity
        self.last_edited_email = repo_functions.get_last_edited_email(
            repo=repo, default_branch_name=self.default_branch_name,
            working_branch_name=self.safe_branch
        )

        self.edit_path = u'/tree/{}/edit/'.format(self.safe_branch)
        self.overview_path = u'/tree/{}/'.format(self.safe_branch)
        self.view_path = u'/tree/{}/view/'.format(self.safe_branch)

        # only build history and working state if requested
        self._history = None
        self._history_summary = None
        self._working_state = None

    @property
    def history(self):
        ''' Get the activity history.
        '''
        if not self._history:
            self._history = self._make_history()

        return self._history

    @property
    def history_summary(self):
        ''' Get the activity history summary.
        '''
        if not self._history_summary:
            self._history_summary = self._make_history_summary()

        return self._history_summary

    @property
    def working_state(self):
        ''' Get the activity working state.
        '''
        if not self._working_state:
            self._working_state = repo_functions.get_activity_working_state(self.repo, self.default_branch_name, self.safe_branch)

        return self._working_state

    def _get_history_log(self, log_format):
        ''' Get a git log from which to create the activity's history
        '''
        hexsha = self.repo.branches[self.safe_branch].commit.hexsha
        return self.repo.git.log('--format={}'.format(log_format), '--date=relative', 'master..{}'.format(hexsha))

    def _construct_history(self):
        ''' Create a list of log items from the raw history log
        '''
        # see <http://git-scm.com/docs/git-log> for placeholders
        log = self._get_history_log(log_format='%x00Name: %an\tEmail: %ae\tDate: %ad\tSubject: %s\tBody: %b%x00')

        history = []
        pattern = re.compile(r'\x00Name: (.*?)\tEmail: (.*?)\tDate: (.*?)\tSubject: (.*?)\tBody: (.*?)\x00', re.DOTALL)
        for log_details in pattern.findall(log):
            name, email, date, subject, body = tuple([item for item in log_details])
            # convert the body to a json object
            try:
                body = json.loads(body)
                message = body['message'] if 'message' in body else u''
            except ValueError:
                # NOTE: don't break if this is an old-style commit message
                message = body
            commit_category, commit_type, commit_action = repo_functions.get_commit_classification(subject, body)
            log_item = dict(author_name=name, author_email=email, commit_date=date, commit_subject=subject,
                            commit_body=body, commit_category=commit_category, commit_type=commit_type,
                            commit_action=commit_action, message=message)
            history.append(log_item)

        return history

    def _make_history(self):
        ''' Make an easily-parsable history of the activity since it was created.
        '''
        history = self._construct_history()
        return history

    def _make_history_summary(self):
        ''' Make an object that summarizes the activity's history.

            The object looks like this:
            {
                'summary': u'3 articles and 1 category have been changed',
                'changes': [
                    {'edit_path': u'', 'display_type': u'Article', 'actions': u'Created, Edited, Deleted', 'title': u'How to Find Us'},
                    {'edit_path': u'/tree/34246e3/edit/contact/hours-of-operation/', 'display_type': u'Article', 'actions': u'Created, Edited', 'title': u'Hours of Operation'},
                    {'edit_path': u'/tree/34246e3/edit/contact/driving-directions/', 'display_type': u'Article', 'actions': u'Created, Edited', 'title': u'Driving Directions'},
                    {'edit_path': u'/tree/34246e3/edit/contact/', 'display_type': u'Category', 'actions': u'Created', 'title': u'Contact'}
                ]
            }
        '''
        # an empty summary object
        history_summary = dict(summary=u'', changes=[])

        ed_lookup = {'create': u'created', 'edit': u'edited', 'delete': u'deleted'}
        change_lookup = {}
        display_types_encountered = []
        # we only care about edits
        edit_history = [action for action in reversed(self.history) if action['commit_category'] == constants.COMMIT_CATEGORY_EDIT]
        for action in edit_history:
            # get the list of changed files from the commit body
            commit_body = action['commit_body']
            # don't continue if the commit body's not a dict
            if type(commit_body) is not dict:
                continue

            # step through the changed files
            # NOTE: don't break if this is an old-style commit message
            actions = commit_body['actions'] if 'actions' in commit_body else commit_body
            for file_change in actions:
                # the passed title or the filename if no title is there
                title = file_change['title'] or file_change['file_path'].split('/')[-1]
                # the passed display type or Unknown if no type is there
                display_type = file_change['display_type'] or u'unknown'
                # how to represent the display type in the interface (i.e. Category -> Topic)
                show_type = constants.LAYOUT_DISPLAY_LOOKUP[display_type] if display_type in constants.LAYOUT_DISPLAY_LOOKUP else display_type
                display_type = display_type.title()<commit_msg>fixed summary on old-style activities<commit_after># -- coding: utf-8 --
from __future__ import absolute_import

import re
import json
from os.path import join
from collections import Counter
from datetime import datetime
from . import constants, repo_functions

class ChimeActivity:
    ''' A representation of an activity in Chime
    '''
    def __init__(self, repo, branch_name, default_branch_name, actor_email):
        ''' Create a new activity.
        '''
        self.repo = repo
        self.safe_branch = branch_name
        self.default_branch_name = default_branch_name

        task_metadata = repo_functions.get_task_metadata_for_branch(self.repo, self.safe_branch)
        self.author_email, self.task_description = self._process_task_metadata(task_metadata)

        self.review_state, self.review_authorized = repo_functions.get_review_state_and_authorized(
            repo=self.repo, default_branch_name=self.default_branch_name,
            working_branch_name=self.safe_branch, actor_email=actor_email
        )

        self.date_created = self.repo.git.log(self.safe_branch, '--format=%ad', '--date=relative', '--', repo_functions.TASK_METADATA_FILENAME).split('\n')[-1]
        self.date_updated = self.repo.git.log(self.safe_branch, '-1', '--format=%ad', '--date=relative')

        # the email of the last person who edited the activity
        self.last_edited_email = repo_functions.get_last_edited_email(
            repo=repo, default_branch_name=self.default_branch_name,
            working_branch_name=self.safe_branch
        )

        self.edit_path = u'/tree/{}/edit/'.format(self.safe_branch)
        self.overview_path = u'/tree/{}/'.format(self.safe_branch)
        self.view_path = u'/tree/{}/view/'.format(self.safe_branch)

        # only build history and working state if requested
        self._history = None
        self._history_summary = None
        self._working_state = None

    @property
    def history(self):
        ''' Get the activity history.
        '''
        if not self._history:
            self._history = self._make_history()

        return self._history

    @property
    def history_summary(self):
        ''' Get the activity history summary.
        '''
        if not self._history_summary:
            self._history_summary = self._make_history_summary()

        return self._history_summary

    @property
    def working_state(self):
        ''' Get the activity working state.
        '''
        if not self._working_state:
            self._working_state = repo_functions.get_activity_working_state(self.repo, self.default_branch_name, self.safe_branch)

        return self._working_state

    def _get_history_log(self, log_format):
        ''' Get a git log from which to create the activity's history
        '''
        hexsha = self.repo.branches[self.safe_branch].commit.hexsha
        return self.repo.git.log('--format={}'.format(log_format), '--date=relative', 'master..{}'.format(hexsha))

    def _construct_history(self):
        ''' Create a list of log items from the raw history log
        '''
        # see <http://git-scm.com/docs/git-log> for placeholders
        log = self._get_history_log(log_format='%x00Name: %an\tEmail: %ae\tDate: %ad\tSubject: %s\tBody: %b%x00')

        history = []
        pattern = re.compile(r'\x00Name: (.*?)\tEmail: (.*?)\tDate: (.*?)\tSubject: (.*?)\tBody: (.*?)\x00', re.DOTALL)
        for log_details in pattern.findall(log):
            name, email, date, subject, body = tuple([item for item in log_details])
            # convert the body to a json object
            try:
                body = json.loads(body)
                message = body['message'] if 'message' in body else u''
            except ValueError:
                # NOTE: don't break if this is an old-style commit message
                message = body
            commit_category, commit_type, commit_action = repo_functions.get_commit_classification(subject, body)
            log_item = dict(author_name=name, author_email=email, commit_date=date, commit_subject=subject,
                            commit_body=body, commit_category=commit_category, commit_type=commit_type,
                            commit_action=commit_action, message=message)
            history.append(log_item)

        return history

    def _make_history(self):
        ''' Make an easily-parsable history of the activity since it was created.
        '''
        history = self._construct_history()
        return history

    def _make_history_summary(self):
        ''' Make an object that summarizes the activity's history.

            The object looks like this:
            {
                'summary': u'3 articles and 1 category have been changed',
                'changes': [
                    {'edit_path': u'', 'display_type': u'Article', 'actions': u'Created, Edited, Deleted', 'title': u'How to Find Us'},
                    {'edit_path': u'/tree/34246e3/edit/contact/hours-of-operation/', 'display_type': u'Article', 'actions': u'Created, Edited', 'title': u'Hours of Operation'},
                    {'edit_path': u'/tree/34246e3/edit/contact/driving-directions/', 'display_type': u'Article', 'actions': u'Created, Edited', 'title': u'Driving Directions'},
                    {'edit_path': u'/tree/34246e3/edit/contact/', 'display_type': u'Category', 'actions': u'Created', 'title': u'Contact'}
                ]
            }
        '''
        # an empty summary object
        history_summary = dict(summary=u'', changes=[])

        ed_lookup = {'create': u'created', 'edit': u'edited', 'delete': u'deleted'}
        change_lookup = {}
        display_types_encountered = []
        # we only care about edits
        edit_history = [action for action in reversed(self.history) if action['commit_category'] == constants.COMMIT_CATEGORY_EDIT]
        for action in edit_history:
            # get the list of changed files from the commit body
            commit_body = action['commit_body']
            # don't continue if the commit body's not a dict or list
            if type(commit_body) is not dict and type(commit_body) is not list:
                continue

            # step through the changed files
            # NOTE: don't break if this is an old-style commit message
            actions = commit_body['actions'] if 'actions' in commit_body else commit_body
            for file_change in actions:
                # the passed title or the filename if no title is there
                title = file_change['title'] or file_change['file_path'].split('/')[-1]
                # the passed display type or Unknown if no type is there
                display_type = file_change['display_type'] or u'unknown'
                # how to represent the display type in the interface (i.e. Category -> Topic)
                show_type = constants.LAYOUT_DISPLAY_LOOKUP[display_type] if display_type in constants.LAYOUT_DISPLAY_LOOKUP else display_type
                display_type = display_type.title()
{'fraction_non_alphanumeric': 0.10703560703560704, 'fraction_numerical': 0.004576004576004576, 'mean_word_length': 2.5187421383647797, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6475458', 'n_tokens_mistral': 3983, 'n_tokens_neox': 3824, 'n_words': 1004}