# 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
                pr_id=context['context'].pr_id,
                title=html_escape(context['context'].message, quote=False),
            ),
            'short': False
        })

    actor = context['context'].actor
    attachment = {
        'fallback': title,
        'title': title,
        'color': color,
        'title_link': context['build_log_url'],
        'fields': fields,
        'footer': context['context'].repo_name,
        'ts': int(time.time()),
        'author_name': actor['display_name'],
        'author_link': actor['links']['html']['href'],
        'author_icon': actor['links']['avatar']['href'],
    }
    if context['context'].type in {'branch', 'tag'}:
        attachment['text'] = context['context'].message
    payload = {'attachments': [attachment]}
    session = requests.Session()
    for webhook in webhooks:
        logger.info('Triggering Slack webhook %s', webhook)
        res = session.post(webhook, json=payload, timeout=10)
        try:
            res.raise_for_status()
        except requests.RequestException:
            logger.exception('Error triggering Slack webhook %s', webhook)

# 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

                pr_id=context['context'].pr_id,
                title=html_escape(context['context'].message, quote=False),
            ),
            'short': False
        })

    actor = context['context'].actor
    attachment = {
        'fallback': title,
        'title': title,
        'color': color,
        'title_link': context['build_log_url'],
        'fields': fields,
        'footer': context['context'].repo_name,
        'ts': int(time.time()),
        'author_name': actor['display_name'],
        'author_link': actor['links']['html']['href'],
        'author_icon': actor['links']['avatar']['href'],
    }
    if context['context'].type in {'branch', 'tag'}:
        attachment['text'] = context['context'].message
    payload = {'attachments': [attachment]}
    session = requests.Session()
    for webhook in webhooks:
        logger.info('Triggering Slack webhook %s', webhook)
        res = session.post(webhook, json=payload, timeout=10)
        try:
            res.raise_for_status()
        except requests.RequestException:
            logger.exception('Error triggering Slack webhook %s', webhook)

            sentry.captureException()