# Path: badwolf/utils.py
# def to_text(value, encoding='utf-8', errors='ignore'):
#     """Convert value to unicode, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return ''
#     if isinstance(value, str):
#         return value
#     if isinstance(value, bytes):
#         return value.decode(encoding, errors)
#     return str(value)
# 
# def to_binary(value, encoding='utf-8'):
#     """Convert value to binary string, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return b''
#     if isinstance(value, bytes):
#         return value
#     if isinstance(value, str):
#         return value.encode(encoding)
#     return bytes(value)
# 
# def sanitize_sensitive_data(s):
#     return _sanitize_urls(s)
# 
# Path: badwolf/extensions.py

# 
# Path: badwolf/bitbucket.py
# class BuildStatus(object):
#     def __init__(self, client, repo, revision, key, url):
#         self.client = client
#         self.repo = repo
#         self.revision = revision
#         self.key = key
#         self.url = url
# 
#     def get(self):
#         endpoint = '2.0/repositories/{repo}/commit/{revision}/statuses/build/{key}'.format(
#             repo=self.repo,
#             revision=self.revision,
#             key=self.key
#         )
#         return self.client.get(endpoint)
# 
#     def update(self, state, name=None, description=None):
#         endpoint = '2.0/repositories/{repo}/commit/{revision}/statuses/build'.format(
#             repo=self.repo,
#             revision=self.revision
#         )
#         return self.client.post(
#             endpoint,
#             data={
#                 'key': self.key,
#                 'state': state,
#                 'url': self.url,
#                 'name': name,
#                 'description': description,
#             }
#         )
# 
# class BitbucketAPIError(requests.RequestException):
#     """Bitbucket API call error"""
#     def __init__(self, code, error, description, *args, **kwargs):
#         super(BitbucketAPIError, self).__init__(*args, **kwargs)
#         self.code = code
#         self.error = error
#         self.description = description
# 
#     def __repr__(self):
#         return "BitbucketAPIError({}, '{}', '{}')".format(
#             self.code,
#             self.error,
#             self.description
#         )
# 
#     def __str__(self):
#         return 'code: {}, error: {}, description: {}'.format(
#             self.code,
#             self.error,
#             self.description
#         )
# 
# Path: badwolf/notification.py
# def send_mail(recipients, subject, html):
#     logger.info('Sending email to %s', recipients)
#     try:
#         mail.send_message(
#             subject=subject,
#             recipients=recipients,
#             html=html,
#         )
#     except smtplib.SMTPException:
#         logger.exception('Error sending email to %s', recipients)
#         sentry.captureException()


import os
import io
import time
import base64
import logging
import shlex
import deansi
import requests
from html import escape as html_escape
from flask import current_app, render_template, url_for
from requests.exceptions import ReadTimeout
from docker import DockerClient
from docker.errors import APIError, DockerException, ImageNotFound, NotFound
from markupsafe import Markup
from badwolf.utils import to_text, to_binary, sanitize_sensitive_data
from badwolf.extensions import bitbucket, sentry
from badwolf.bitbucket import BuildStatus, BitbucketAPIError
from badwolf.notification import send_mail
        except BitbucketAPIError:
            logger.exception('Error calling Bitbucket API')
            sentry.captureException()

    def send_notifications(self, context):
        exit_code = context['exit_code']
        template = 'test_success' if exit_code == 0 else 'test_failure'
        html = render_template('mail/' + template + '.html', **context)
        html = sanitize_sensitive_data(html)

        # Save log html
        log_dir = os.path.join(current_app.config['BADWOLF_LOG_DIR'], self.commit_hash, self.context.task_id)
        os.makedirs(log_dir, exist_ok=True)
        log_file = os.path.join(log_dir, 'build.html')
        with open(log_file, 'wb') as f:
            f.write(to_binary(html))

        if exit_code == 137:
            logger.info('Build cancelled, will not sending notification')
            return

        test_status = 'succeed' if exit_code == 0 else 'failed'
        subject = 'Test {} for repository {}'.format(test_status, self.context.repository)
        notification = self.spec.notification
        email = notification.email
        should_send_mail = email and email.recipients and (
            (exit_code == 0 and email.on_success == 'always') or
            (exit_code != 0 and email.on_failure == 'always')
        )
        if should_send_mail:

# Path: badwolf/utils.py
# def to_text(value, encoding='utf-8', errors='ignore'):
#     """Convert value to unicode, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return ''
#     if isinstance(value, str):
#         return value
#     if isinstance(value, bytes):
#         return value.decode(encoding, errors)
#     return str(value)
# 
# def to_binary(value, encoding='utf-8'):
#     """Convert value to binary string, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return b''
#     if isinstance(value, bytes):
#         return value
#     if isinstance(value, str):
#         return value.encode(encoding)
#     return bytes(value)
# 
# def sanitize_sensitive_data(s):
#     return _sanitize_urls(s)
# 
# Path: badwolf/extensions.py

# 
# Path: badwolf/bitbucket.py
# class BuildStatus(object):
#     def __init__(self, client, repo, revision, key, url):
#         self.client = client
#         self.repo = repo
#         self.revision = revision
#         self.key = key
#         self.url = url
# 
#     def get(self):
#         endpoint = '2.0/repositories/{repo}/commit/{revision}/statuses/build/{key}'.format(
#             repo=self.repo,
#             revision=self.revision,
#             key=self.key
#         )
#         return self.client.get(endpoint)
# 
#     def update(self, state, name=None, description=None):
#         endpoint = '2.0/repositories/{repo}/commit/{revision}/statuses/build'.format(
#             repo=self.repo,
#             revision=self.revision
#         )
#         return self.client.post(
#             endpoint,
#             data={
#                 'key': self.key,
#                 'state': state,
#                 'url': self.url,
#                 'name': name,
#                 'description': description,
#             }
#         )
# 
# class BitbucketAPIError(requests.RequestException):
#     """Bitbucket API call error"""
#     def __init__(self, code, error, description, *args, **kwargs):
#         super(BitbucketAPIError, self).__init__(*args, **kwargs)
#         self.code = code
#         self.error = error
#         self.description = description
# 
#     def __repr__(self):
#         return "BitbucketAPIError({}, '{}', '{}')".format(
#             self.code,
#             self.error,
#             self.description
#         )
# 
#     def __str__(self):
#         return 'code: {}, error: {}, description: {}'.format(
#             self.code,
#             self.error,
#             self.description
#         )
# 
# Path: badwolf/notification.py
# def send_mail(recipients, subject, html):
#     logger.info('Sending email to %s', recipients)
#     try:
#         mail.send_message(
#             subject=subject,
#             recipients=recipients,
#             html=html,
#         )
#     except smtplib.SMTPException:
#         logger.exception('Error sending email to %s', recipients)
#         sentry.captureException()


# Path: badwolf/builder.py
import os
import io
import time
import base64
import logging
import shlex
import deansi
import requests
from html import escape as html_escape
from flask import current_app, render_template, url_for
from requests.exceptions import ReadTimeout
from docker import DockerClient
from docker.errors import APIError, DockerException, ImageNotFound, NotFound
from markupsafe import Markup
from badwolf.utils import to_text, to_binary, sanitize_sensitive_data
from badwolf.extensions import bitbucket, sentry
from badwolf.bitbucket import BuildStatus, BitbucketAPIError
from badwolf.notification import send_mail

        except BitbucketAPIError:
            logger.exception('Error calling Bitbucket API')
            sentry.captureException()

    def send_notifications(self, context):
        exit_code = context['exit_code']
        template = 'test_success' if exit_code == 0 else 'test_failure'
        html = render_template('mail/' + template + '.html', **context)
        html = sanitize_sensitive_data(html)

        # Save log html
        log_dir = os.path.join(current_app.config['BADWOLF_LOG_DIR'], self.commit_hash, self.context.task_id)
        os.makedirs(log_dir, exist_ok=True)
        log_file = os.path.join(log_dir, 'build.html')
        with open(log_file, 'wb') as f:
            f.write(to_binary(html))

        if exit_code == 137:
            logger.info('Build cancelled, will not sending notification')
            return

        test_status = 'succeed' if exit_code == 0 else 'failed'
        subject = 'Test {} for repository {}'.format(test_status, self.context.repository)
        notification = self.spec.notification
        email = notification.email
        should_send_mail = email and email.recipients and (
            (exit_code == 0 and email.on_success == 'always') or
            (exit_code != 0 and email.on_failure == 'always')
        )
        if should_send_mail:

            send_mail(email.recipients, subject, html)