<commit_before>"""Integration for building changes on Travis CI."""

from __future__ import unicode_literals

import base64
import logging

import yaml
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db import IntegrityError, transaction
from django.utils.functional import cached_property
from djblets.avatars.services import URLAvatarService
from djblets.siteconfig.models import SiteConfiguration
from reviewboard.admin.server import build_server_url
from reviewboard.avatars import avatar_services
from reviewboard.extensions.hooks import SignalHook
from reviewboard.integrations import Integration
from reviewboard.reviews.models.status_update import StatusUpdate
from reviewboard.reviews.signals import review_request_published

from rbintegrations.travisci.api import TravisAPI
from rbintegrations.travisci.forms import TravisCIIntegrationConfigForm


logger = logging.getLogger(__name__)


class TravisCIIntegration(Integration):
    """Integrates Review Board with Travis CI."""

    name = 'Travis CI'
    description = 'Builds diffs posted to Review Board using Travis CI.'
    config_form_cls = TravisCIIntegrationConfigForm

    def initialize(self):
        """Initialize the integration hooks."""
        SignalHook(self, review_request_published,
                   self._on_review_request_published)

    @cached_property
    def icon_static_urls(self):
        """Return the icons used for the integration.

        Returns:
            dict:
            The icons for Travis CI.
        """
        from rbintegrations.extension import RBIntegrationsExtension

        extension = RBIntegrationsExtension.instance

        return {
            '1x': extension.get_static_url('images/travisci/icon.png'),
            '2x': extension.get_static_url('images/travisci/icon@2x.png'),
        }

    def _on_review_request_published(self, sender, review_request,
                                     changedesc=None, **kwargs):
        """Handle when a review request is published.

        Args:
            sender (object):
                The sender of the signal.

            review_request (reviewboard.reviews.models.review_request.
                            ReviewRequest):
                The review request which was published.

            changedesc (reviewboard.changedescs.models.ChangeDescription,
                        optional):
                The change description associated with the publish.

            **kwargs (dict):
                Additional keyword arguments.
        """
        repository = review_request.repository

        # Only build changes against GitHub repositories.
        if not (repository and
                repository.hosting_account and
                repository.hosting_account.service_name == 'github'):
            return

        diffset = review_request.get_latest_diffset()

        # Don't build any review requests that don't include diffs.
        if not diffset:
            return

        # If this was an update to a review request, make sure that there was a
        # diff update in it.
        if changedesc is not None:
            fields_changed = changedesc.fields_changed

            if ('diff' not in fields_changed or
                'added' not in fields_changed['diff']):
                return

        matching_configs = [
            config
            for config in self.get_configs(review_request.local_site)
            if config.match_conditions(form_cls=self.config_form_cls,
                                       review_request=review_request)
        ]

        if not matching_configs:
            return

        user = self._get_or_create_user()

        scmtool = repository.get_scmtool()
        diff_data = base64.b64encode(scmtool.get_parser('').raw_diff(diffset))

        commit_message = '%s\n\n%s' % (review_request.summary,
                                       review_request.description)
        webhook_url = build_server_url(reverse('travis-ci-webhook'))

        for config in matching_configs:
            status_update = StatusUpdate.objects.create(
                service_id='travis-ci',
                user=user,
                summary='Travis CI',
                description='starting build...',
                state=StatusUpdate.PENDING,
                review_request=review_request,
                change_description=changedesc)

            travis_config = yaml.load(config.get('travis_yml'))

            # Add set-up and patching to the start of the "script" section of
            # the config.
            script = travis_config.get('script', [])

            if not isinstance(script, list):
                script = [script]

            travis_config['script'] = [
                'git fetch --unshallow origin',
                'git checkout %s' % diffset.base_commit_id.encode('utf-8'),
                'echo %s | base64 --decode | patch -p1' % diff_data,
            ] + script

            # Set up webhook notifications.
            notifications = travis_config.get('notifications') or {}
            webhooks = notifications.get('webhooks') or {}

            urls = webhooks.get('urls', [])

            if not isinstance(urls, list):
                urls = [urls]

            urls.append(webhook_url)

            webhooks['urls'] = urls<commit_msg>Add the `Loader` argument to `yaml.load`.<commit_after>"""Integration for building changes on Travis CI."""

from __future__ import unicode_literals

import base64
import logging

import yaml
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db import IntegrityError, transaction
from django.utils.functional import cached_property
from djblets.avatars.services import URLAvatarService
from djblets.siteconfig.models import SiteConfiguration
from reviewboard.admin.server import build_server_url
from reviewboard.avatars import avatar_services
from reviewboard.extensions.hooks import SignalHook
from reviewboard.integrations import Integration
from reviewboard.reviews.models.status_update import StatusUpdate
from reviewboard.reviews.signals import review_request_published

from rbintegrations.travisci.api import TravisAPI
from rbintegrations.travisci.forms import TravisCIIntegrationConfigForm


logger = logging.getLogger(__name__)


class TravisCIIntegration(Integration):
    """Integrates Review Board with Travis CI."""

    name = 'Travis CI'
    description = 'Builds diffs posted to Review Board using Travis CI.'
    config_form_cls = TravisCIIntegrationConfigForm

    def initialize(self):
        """Initialize the integration hooks."""
        SignalHook(self, review_request_published,
                   self._on_review_request_published)

    @cached_property
    def icon_static_urls(self):
        """Return the icons used for the integration.

        Returns:
            dict:
            The icons for Travis CI.
        """
        from rbintegrations.extension import RBIntegrationsExtension

        extension = RBIntegrationsExtension.instance

        return {
            '1x': extension.get_static_url('images/travisci/icon.png'),
            '2x': extension.get_static_url('images/travisci/icon@2x.png'),
        }

    def _on_review_request_published(self, sender, review_request,
                                     changedesc=None, **kwargs):
        """Handle when a review request is published.

        Args:
            sender (object):
                The sender of the signal.

            review_request (reviewboard.reviews.models.review_request.
                            ReviewRequest):
                The review request which was published.

            changedesc (reviewboard.changedescs.models.ChangeDescription,
                        optional):
                The change description associated with the publish.

            **kwargs (dict):
                Additional keyword arguments.
        """
        repository = review_request.repository

        # Only build changes against GitHub repositories.
        if not (repository and
                repository.hosting_account and
                repository.hosting_account.service_name == 'github'):
            return

        diffset = review_request.get_latest_diffset()

        # Don't build any review requests that don't include diffs.
        if not diffset:
            return

        # If this was an update to a review request, make sure that there was a
        # diff update in it.
        if changedesc is not None:
            fields_changed = changedesc.fields_changed

            if ('diff' not in fields_changed or
                'added' not in fields_changed['diff']):
                return

        matching_configs = [
            config
            for config in self.get_configs(review_request.local_site)
            if config.match_conditions(form_cls=self.config_form_cls,
                                       review_request=review_request)
        ]

        if not matching_configs:
            return

        user = self._get_or_create_user()

        scmtool = repository.get_scmtool()
        diff_data = base64.b64encode(scmtool.get_parser('').raw_diff(diffset))

        commit_message = '%s\n\n%s' % (review_request.summary,
                                       review_request.description)
        webhook_url = build_server_url(reverse('travis-ci-webhook'))

        for config in matching_configs:
            status_update = StatusUpdate.objects.create(
                service_id='travis-ci',
                user=user,
                summary='Travis CI',
                description='starting build...',
                state=StatusUpdate.PENDING,
                review_request=review_request,
                change_description=changedesc)

            travis_config = yaml.load(config.get('travis_yml'),
                                      Loader=yaml.SafeLoader)

            # Add set-up and patching to the start of the "script" section of
            # the config.
            script = travis_config.get('script', [])

            if not isinstance(script, list):
                script = [script]

            travis_config['script'] = [
                'git fetch --unshallow origin',
                'git checkout %s' % diffset.base_commit_id.encode('utf-8'),
                'echo %s | base64 --decode | patch -p1' % diff_data,
            ] + script

            # Set up webhook notifications.
            notifications = travis_config.get('notifications') or {}
            webhooks = notifications.get('webhooks') or {}

            urls = webhooks.get('urls', [])

            if not isinstance(urls, list):
                urls = [urls]

            urls.append(webhook_url)

            webhooks['urls'] = urls
{'fraction_non_alphanumeric': 0.07472222222222222, 'fraction_numerical': 0.0024074074074074076, 'mean_word_length': 2.139825581395349, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4317658', 'n_tokens_mistral': 2830, 'n_tokens_neox': 2681, 'n_words': 709}