<commit_before>'''
:Author: Juti Noppornpitak

This package contains an abstract controller (based on :class:`tornado.web.RequestHandler`) and built-in controllers.
'''

from os        import path as p
from mimetypes import guess_type as get_type
from re        import match, sub
from StringIO  import StringIO
from time      import time

from tornado.web import HTTPError, ErrorHandler, RequestHandler

from tori           import __version__
from tori.centre    import services as ToriService
from tori.common    import Enigma, Console
from tori.exception import *
from tori.renderer  import DefaultRenderer
from tori.service.data.base import ResourceEntity

class Controller(RequestHandler):
    '''
    The abstract controller for Tori framework which replaces Jinja2 as a template engine instead.
    '''

    def __init__(self, *args, **kwargs):
        RequestHandler.__init__(self, *args, **kwargs)

        self.session_id   = None
        self.session_repo = None

        # Start the session if the session component is registered.
        self._start_session()

    def _start_session(self):
        ''' Start the session. '''
        if not ToriService.has('session') or 'cookie_secret' not in self.settings:
            return

        self.session_repo = ToriService.get('session')
        self.session_id   = self.get_secure_cookie('ssid')

        if not self.session_id:
            self.session_id = self.session_repo.generate()

            self.set_secure_cookie('ssid', self.session_id)

    def component(self, name):
        '''
        Get the (re-usable) component from the initialized Imagination component locator service.

        :param `name`: the name of the registered re-usable component.
        :return:       module, package registered or ``None``
        '''
        return ToriService.has(name) and ToriService.get(name) or None

    def session(self, key, new_content=None):
        '''
        Get the session or set it if ``new_content`` is set.

        :param `key`:         Session data key
        :param `new_content`: Session data content

        :return: the data stored in the session or ``None``
        '''
        if not self.session_repo:
            raise SessionError, 'This session component is not initialized.'

        if new_content:
            self.session_repo.set(self.session_id, key, new_content)
            return new_content

        session = self.session_repo.get(self.session_id, key)

        return session

    def delete_session(self, key):
        self.component('session').delete(self.session_id, key)

    def render_template(self, template_name, **contexts):
        '''
        Render the template with the given contexts.

        See :meth:`tori.renderer.Renderer.render` for more information.
        '''

        # If the rendering source isn't set, break the code.
        if not self._rendering_source:
            raise RenderingSourceMissingError, 'The source of template is not identified. This method is disabled.'

        # If the rendering engine is not specified, use the default one.
        if not self._rendering_engine:
            self._rendering_engine = DefaultRenderer

        output = None

        try:
            output = self.component('renderer').render(
                self._rendering_source,
                template_name,
                **contexts
            )
        except RendererNotFoundError:
            # When the renderer is not found. It is possible that the renderer is not yet
            # instantiated. This block of the code will do the lazy loading.
            renderer = self._rendering_engine(self._rendering_source)
            output   = self.component('renderer').register(renderer).render(
                self._rendering_source,
                template_name,
                **contexts
            )

        if not output:
            raise UnexpectedComputationError, 'Detected the rendering service malfunctioning.'

        return output

    def render(self, template_name, **contexts):
        '''
        Render the template with the given contexts and push the output buffer.

        See :meth:`tori.renderer.Renderer.render` for more information.
        '''
        self.write(self.render_template(template_name, **contexts))

class RestController(Controller):
    '''
    Abstract REST-capable controller based on a single primary key.
    '''
    def list(self):
        ''' Retrieve the list of all entities. '''
        self.set_status(405)

    def retrieve(self, id):
        ''' Retrieve an entity with `id`. '''
        self.set_status(405)

    def create(self):
        ''' Create an entity. '''
        self.set_status(405)

    def remove(self, id):
        ''' Remove an entity with `id`. '''
        self.set_status(405)

    def update(self, id):
        ''' Update an entity with `id`. '''
        self.set_status(405)

    def get(self, id=None):
        ''' Handle GET requests. '''
        if not id:
            self.list()
            return

        self.retrieve(int(id))

    def post(self, id=None):
        ''' Handle POST requests. '''
        if id:
            self.set_status(405)
            return

        self.create()

    def put(self, id=None):
        ''' Handle PUT requests. '''
        if not id:
            self.set_status(405)
            return

        self.update(int(id))

    def delete(self, id=None):
        ''' Handle DELETE requests. '''
        if id:
            self.set_status(405)
            return

        self.remove(int(id))

class ErrorController(Controller):
    """Generates an error response with status_code for all requests."""
    def initialize(self, status_code):
        self.set_status(status_code)

    def prepare(self):
        raise HTTPError(self._status_code)

class ResourceService(RequestHandler):
    ''' Resource service is to serve a static resource via HTTP/S protocal. '''

    _patterns      = {}
    _cache_objects = {}

    _plugins            = {}
    _plugins_tag_name   = 'resource-service-plugin'
    _plugins_registered = False

    @staticmethod
    def add_pattern(pattern, base_path, enabled_cache=False):
        '''
        Add the routing pattern for the resource path prefix.

        :param pattern: a routing pattern. It can be a Python-compatible regular expression.

        :param base_path: a path prefix of the resource corresponding to the routing pattern.

        :param enabled_cache: a flag to indicate whether any loaded resources need to be cached on the first request.
        '''

        ResourceService._patterns[pattern] = base_path

    def get(self, *path):
        '''
        Get a particular resource.

        :param path: blocks of path used to composite an actual path.

        .. note::
            This method requires refactoring.
        '''
        base_path    = None
        resource     = None
        used_pattern = None
        request_uri  = self.request.uri

        # Remove the prefixed foreslashes.
        path = '/'.join(path)
        path = sub('^/+', '', path)

        # If the request URI is already pre-calculated or fixed, load the
        # entity from the corresponding path.
        if ResourceService._patterns.has_key(request_uri):
            resource = self._get_resource_entity(ResourceService._patterns[request_uri])

        # When the resource is not loaded, try to get from the wildcard pattern.
        if not resource:
            resource = self._get_resource_on_non_precalculated_pattern(path)

        # Get the resource type.
        resource_type = resource.type or 'text/plain'

        self.set_header("Content-Type", resource_type)

        # Return HTTP 404 if the content is not found.
        if not resource.content():
            raise HTTPError, 404

        # Retrieve the plugins if registered.
        if not ResourceService._plugins_registered:
            ResourceService._plugins = ToriService.getListByTag(
                ResourceService._plugins_tag_name
            )

        # Apply the plugin.
        for plugin in ResourceService._plugins:
            if plugin.expect(resource):
                resource = plugin.execute(resource)
            # End the iteraltion

        # Return the content.
        try:
            self.finish(resource.content())
        except Exception, e:
            print 'Failed on resource distribution.'
            print e, type(e)

    def _get_resource_entity(self, real_path):
        return ResourceEntity(real_path)

    def _get_resource_on_non_precalculated_pattern(self, path_to_resource):
        request_uri = self.request.uri

        for pattern in ResourceService._patterns:
            if not match(pattern, request_uri):
                continue

            used_pattern = pattern
            real_path    = p.abspath(p.join(
                ResourceService._patterns[pattern],
                path_to_resource
            ))

            return self._get_resource_entity(real_path)

        raise HTTPError, 404<commit_msg>Renamed the variables, fixed bugs on ResourceService and allowed the application to automatically enable unsecure session.<commit_after>'''
:Author: Juti Noppornpitak

This package contains an abstract controller (based on :class:`tornado.web.RequestHandler`) and built-in controllers.
'''

from os        import path as p
from mimetypes import guess_type as get_type
from re        import match, sub
from StringIO  import StringIO
from time      import time

from tornado.web import HTTPError, ErrorHandler, RequestHandler

from tori           import __version__
from tori.centre    import services as ComponentRepository
from tori.common    import Console, Enigma
from tori.exception import *
from tori.renderer  import DefaultRenderer
from tori.service.data.base import ResourceEntity

class Controller(RequestHandler):
    '''
    The abstract controller for Tori framework which replaces Jinja2 as a template engine instead.
    '''

    def __init__(self, *args, **kwargs):
        RequestHandler.__init__(self, *args, **kwargs)

        self.session_id   = None
        self.session_repo = None

        # Start the session if the session component is registered.
        self.start_session()

    def start_session(self):
        ''' Start the session. '''
        if not ComponentRepository.has('session'):
            return

        self.session_repo = ComponentRepository.get('session')
        self.session_id   = self._can_use_secure_cookie() and self.get_secure_cookie('ssid') or self.get_cookie('ssid')

        if self.session_id:
            return

        self.session_id = self.session_repo.generate()

        if self._can_use_secure_cookie():
            self.set_secure_cookie('ssid', self.session_id)
        else:
            Console.log('%s: Use unsecure session.' % self.__class__.__name__)
            self.set_cookie('ssid', self.session_id)
        # endif

    def _can_use_secure_cookie(self):
        return 'cookie_secret' in self.settings and self.settings['cookie_secret']

    def component(self, name, fork_component=False):
        '''
        Get the (re-usable) component from the initialized Imagination component locator service.

        :param `name`:           the name of the registered re-usable component.
        :param `fork_component`: the flag to fork the component
        :return:                 module, package registered or ``None``
        '''

        if not ComponentRepository.has(name):
            return None

        return fork_component and ComponentRepository.fork(name) or ComponentRepository.get(name)

    def session(self, key, new_content=None):
        '''
        Get the session or set it if ``new_content`` is set.

        :param `key`:         Session data key
        :param `new_content`: Session data content

        :return: the data stored in the session or ``None``
        '''
        if not self.session_repo:
            raise SessionError, 'This session component is not initialized.'

        if new_content:
            self.session_repo.set(self.session_id, key, new_content)
            return new_content

        session = self.session_repo.get(self.session_id, key)

        return session

    def delete_session(self, key):
        self.component('session').delete(self.session_id, key)

    def render_template(self, template_name, **contexts):
        '''
        Render the template with the given contexts.

        See :meth:`tori.renderer.Renderer.render` for more information.
        '''

        # If the rendering source isn't set, break the code.
        if not self._rendering_source:
            raise RenderingSourceMissingError, 'The source of template is not identified. This method is disabled.'

        # If the rendering engine is not specified, use the default one.
        if not self._rendering_engine:
            self._rendering_engine = DefaultRenderer

        output = None

        try:
            output = self.component('renderer').render(
                self._rendering_source,
                template_name,
                **contexts
            )
        except RendererNotFoundError:
            # When the renderer is not found. It is possible that the renderer is not yet
            # instantiated. This block of the code will do the lazy loading.
            renderer = self._rendering_engine(self._rendering_source)
            output   = self.component('renderer').register(renderer).render(
                self._rendering_source,
                template_name,
                **contexts
            )

        if not output:
            raise UnexpectedComputationError, 'Detected the rendering service malfunctioning.'

        return output

    def render(self, template_name, **contexts):
        '''
        Render the template with the given contexts and push the output buffer.

        See :meth:`tori.renderer.Renderer.render` for more information.
        '''
        self.write(self.render_template(template_name, **contexts))

class RestController(Controller):
    '''
    Abstract REST-capable controller based on a single primary key.
    '''
    def list(self):
        ''' Retrieve the list of all entities. '''
        self.set_status(405)

    def retrieve(self, id):
        ''' Retrieve an entity with `id`. '''
        self.set_status(405)

    def create(self):
        ''' Create an entity. '''
        self.set_status(405)

    def remove(self, id):
        ''' Remove an entity with `id`. '''
        self.set_status(405)

    def update(self, id):
        ''' Update an entity with `id`. '''
        self.set_status(405)

    def get(self, id=None):
        ''' Handle GET requests. '''
        if not id:
            self.list()
            return

        self.retrieve(int(id))

    def post(self, id=None):
        ''' Handle POST requests. '''
        if id:
            self.set_status(405)
            return

        self.create()

    def put(self, id=None):
        ''' Handle PUT requests. '''
        if not id:
            self.set_status(405)
            return

        self.update(int(id))

    def delete(self, id=None):
        ''' Handle DELETE requests. '''
        if id:
            self.set_status(405)
            return

        self.remove(int(id))

class ErrorController(Controller):
    """Generates an error response with status_code for all requests."""
    def initialize(self, status_code):
        self.set_status(status_code)

    def prepare(self):
        raise HTTPError(self._status_code)

class ResourceService(RequestHandler):
    ''' Resource service is to serve a static resource via HTTP/S protocal. '''

    _patterns      = {}
    _cache_objects = {}

    _plugins            = {}
    _plugins_tag_name   = 'resource-service-plugin'
    _plugins_registered = False

    @staticmethod
    def add_pattern(pattern, base_path, enabled_cache=False):
        '''
        Add the routing pattern for the resource path prefix.

        :param pattern: a routing pattern. It can be a Python-compatible regular expression.

        :param base_path: a path prefix of the resource corresponding to the routing pattern.

        :param enabled_cache: a flag to indicate whether any loaded resources need to be cached on the first request.
        '''

        ResourceService._patterns[pattern] = base_path

    def get(self, *path):
        '''
        Get a particular resource.

        :param path: blocks of path used to composite an actual path.

        .. note::
            This method requires refactoring.
        '''
        base_path    = None
        resource     = None
        used_pattern = None
        request_uri  = self.request.uri

        # Remove the prefixed foreslashes.
        path = '/'.join(path)
        path = sub('^/+', '', path)

        # If the request URI is already pre-calculated or fixed, load the
        # entity from the corresponding path.
        if ResourceService._patterns.has_key(request_uri):
            resource = self._get_resource_entity(ResourceService._patterns[request_uri])

        # When the resource is not loaded, try to get from the wildcard pattern.
        if not resource:
            resource = self._get_resource_on_non_precalculated_pattern(path)

        # Get the resource type.
        resource_type = resource.type or 'text/plain'

        self.set_header("Content-Type", resource_type)

        # Return HTTP 404 if the content is not found.
        if not resource.exists():
            raise HTTPError, 404

        # Retrieve the plugins if registered.
        if not ResourceService._plugins_registered:
            ResourceService._plugins = ComponentRepository.getListByTag(
                ResourceService._plugins_tag_name
            )

        # Apply the plugin.
        for plugin in ResourceService._plugins:
            if plugin.expect(resource):
                resource = plugin.execute(resource)
            # End the iteraltion

        # Return the content.
        try:
            self.finish(resource.content())
        except Exception, e:
            print 'Failed on resource distribution.'
            print e, type(e)

    def _get_resource_entity(self, real_path):
        return ResourceEntity(real_path)

    def _get_resource_on_non_precalculated_pattern(self, path_to_resource):
        request_uri = self.request.uri

        for pattern in ResourceService._patterns:
            if not match(pattern, request_uri):
                continue

            used_pattern = pattern
            real_path    = p.abspath(p.join(
                ResourceService._patterns[pattern],
                path_to_resource
            ))

            return self._get_resource_entity(real_path)

        raise HTTPError, 404<|endoftext|>


<commit_before>import os
import tempfile
import shutil

from mock import Mock, patch
import yaml

from dusty import constants
from dusty.systems.docker.compose import (_write_composefile, _get_docker_env,
                                   _get_dusty_containers, _get_canonical_container_name,
                                   _get_exited_dusty_containers, get_dusty_images,
                                   _get_container_for_app_or_service,
                                   _exec_in_container)
from dusty.compiler.spec_assembler import get_specs
from ...utils import DustyTestCase

class TestComposeSystem(DustyTestCase):
    def setUp(self):
        super(TestComposeSystem, self).setUp()
        self.temp_compose_dir = tempfile.mkdtemp()
        self.temp_compose_path = os.path.join(self.temp_compose_dir, 'docker-compose.yml')
        self.old_compose_dir = constants.COMPOSE_DIR
        self.old_compose_path = constants.COMPOSEFILE_PATH
        constants.COMPOSE_DIR = self.temp_compose_dir
        constants.COMPOSEFILE_PATH = self.temp_compose_path
        self.test_spec = {'app-a': {'image': 'app/a'}}

        self.containers_return = [{'Names': ['/dusty_app-a_1'], 'Status': 'Exited'},
                                  {'Names': ['/dusty_app-b_1', '/dusty_app-a_1/dusty_app-b_1'], 'Status': 'Running'},
                                  {'Names': ['/some-random-image']}]
        self.fake_docker_client = Mock()
        self.fake_docker_client.containers.return_value = self.containers_return
        # self.fake_docker_client.

    def tearDown(self):
        super(TestComposeSystem, self).tearDown()
        constants.COMPOSE_DIR = self.old_compose_dir
        constants.COMPOSEFILE_PATH = self.old_compose_path
        shutil.rmtree(self.temp_compose_dir)

    def test_write_composefile(self):
        _write_composefile(self.test_spec)
        written = open(self.temp_compose_path, 'r').read()
        self.assertItemsEqual(yaml.load(written), self.test_spec)

    @patch('dusty.demote.get_config_value')
    @patch('dusty.systems.compose.check_output_demoted')
    def test_get_docker_env(self, fake_check_output, fake_config_value):
        fake_config_value.return_value = 'root'
        fake_check_output.return_value = """    export DOCKER_TLS_VERIFY=1
        export DOCKER_HOST=tcp://192.168.59.103:2376
        export DOCKER_CERT_PATH=/Users/root/.boot2docker/certs/boot2docker-vm"""
        expected = {'DOCKER_TLS_VERIFY': '1',
                    'DOCKER_HOST': 'tcp://192.168.59.103:2376',
                    'DOCKER_CERT_PATH': '/Users/root/.boot2docker/certs/boot2docker-vm'}
        result = _get_docker_env()
        self.assertItemsEqual(result, expected)

    def test_get_dusty_containers_falsy(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, []),
                         self.containers_return[:-1])

    def test_get_dusty_containers_short_name(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, ['app-a']),
                         [self.containers_return[0]])

    def test_get_dusty_containers_long_name(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, ['app-b']),
                         [self.containers_return[1]])

    def test_get_canonical_container_name(self):
        self.assertEqual(_get_canonical_container_name(self.containers_return[1]), 'dusty_app-b_1')

    def test_get_exited_containers(self):
        self.assertEqual(_get_exited_dusty_containers(self.fake_docker_client), [self.containers_return[0]])

    def test_get_dusty_images(self):
        self.assertEqual(get_dusty_images(), set(['app/a:latest', 'app/b:latest', 'service/a:latest']))

    def test_get_container_for_app_or_service(self):
        result = _get_container_for_app_or_service(self.fake_docker_client, 'app-a')
        self.assertIn('/dusty_app-a_1', result['Names'])

    def test_get_container_for_app_or_service_none_found(self):
        result = _get_container_for_app_or_service(self.fake_docker_client, 'app-c')
        self.assertIsNone(result)

    def test_get_container_for_app_or_service_none_found_with_raise(self):
        with self.assertRaises(RuntimeError):
            _get_container_for_app_or_service(self.fake_docker_client,
                                              'app-c',
                                              raise_if_not_found=True)

    def test_exec_in_container_with_args(self):
        self.fake_docker_client.exec_create.return_value = {'Id': 'exec-id'}
        fake_container = {'Id': 'container-id'}
        _exec_in_container(self.fake_docker_client, fake_container, 'cp -r', '/tmp/a', '/tmp/b')
        self.fake_docker_client.exec_create.assert_called_once_with('container-id', 'cp -r /tmp/a /tmp/b')

    def test_exec_in_container_without_args(self):
        self.fake_docker_client.exec_create.return_value = {'Id': 'exec-id'}
        fake_container = {'Id': 'container-id'}
        _exec_in_container(self.fake_docker_client, fake_container, 'ls')
        self.fake_docker_client.exec_create.assert_called_once_with('container-id', 'ls')
<commit_msg>fixed another import thingy<commit_after>import os
import tempfile
import shutil

from mock import Mock, patch
import yaml

from dusty import constants
from dusty.systems.docker import (_get_docker_env, get_dusty_containers, get_dusty_images, _get_container_for_app_or_service,
                                  _get_canonical_container_name, _exec_in_container)

from dusty.systems.docker.compose import _write_composefile
from dusty.compiler.spec_assembler import get_specs
from ....utils import DustyTestCase

class TestComposeSystem(DustyTestCase):
    def setUp(self):
        super(TestComposeSystem, self).setUp()
        self.temp_compose_dir = tempfile.mkdtemp()
        self.temp_compose_path = os.path.join(self.temp_compose_dir, 'docker-compose.yml')
        self.old_compose_dir = constants.COMPOSE_DIR
        self.old_compose_path = constants.COMPOSEFILE_PATH
        constants.COMPOSE_DIR = self.temp_compose_dir
        constants.COMPOSEFILE_PATH = self.temp_compose_path
        self.test_spec = {'app-a': {'image': 'app/a'}}

        self.containers_return = [{'Names': ['/dusty_app-a_1'], 'Status': 'Exited'},
                                  {'Names': ['/dusty_app-b_1', '/dusty_app-a_1/dusty_app-b_1'], 'Status': 'Running'},
                                  {'Names': ['/some-random-image']}]
        self.fake_docker_client = Mock()
        self.fake_docker_client.containers.return_value = self.containers_return
        # self.fake_docker_client.

    def tearDown(self):
        super(TestComposeSystem, self).tearDown()
        constants.COMPOSE_DIR = self.old_compose_dir
        constants.COMPOSEFILE_PATH = self.old_compose_path
        shutil.rmtree(self.temp_compose_dir)

    def test_write_composefile(self):
        _write_composefile(self.test_spec)
        written = open(self.temp_compose_path, 'r').read()
        self.assertItemsEqual(yaml.load(written), self.test_spec)

    @patch('dusty.demote.get_config_value')
    @patch('dusty.systems.compose.check_output_demoted')
    def test_get_docker_env(self, fake_check_output, fake_config_value):
        fake_config_value.return_value = 'root'
        fake_check_output.return_value = """    export DOCKER_TLS_VERIFY=1
        export DOCKER_HOST=tcp://192.168.59.103:2376
        export DOCKER_CERT_PATH=/Users/root/.boot2docker/certs/boot2docker-vm"""
        expected = {'DOCKER_TLS_VERIFY': '1',
                    'DOCKER_HOST': 'tcp://192.168.59.103:2376',
                    'DOCKER_CERT_PATH': '/Users/root/.boot2docker/certs/boot2docker-vm'}
        result = _get_docker_env()
        self.assertItemsEqual(result, expected)

    def test_get_dusty_containers_falsy(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, []),
                         self.containers_return[:-1])

    def test_get_dusty_containers_short_name(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, ['app-a']),
                         [self.containers_return[0]])

    def test_get_dusty_containers_long_name(self):
        self.assertEqual(_get_dusty_containers(self.fake_docker_client, ['app-b']),
                         [self.containers_return[1]])

    def test_get_canonical_container_name(self):
        self.assertEqual(_get_canonical_container_name(self.containers_return[1]), 'dusty_app-b_1')

    def test_get_exited_containers(self):
        self.assertEqual(_get_exited_dusty_containers(self.fake_docker_client), [self.containers_return[0]])

    def test_get_dusty_images(self):
        self.assertEqual(get_dusty_images(), set(['app/a:latest', 'app/b:latest', 'service/a:latest']))

    def test_get_container_for_app_or_service(self):
        result = _get_container_for_app_or_service(self.fake_docker_client, 'app-a')
        self.assertIn('/dusty_app-a_1', result['Names'])

    def test_get_container_for_app_or_service_none_found(self):
        result = _get_container_for_app_or_service(self.fake_docker_client, 'app-c')
        self.assertIsNone(result)

    def test_get_container_for_app_or_service_none_found_with_raise(self):
        with self.assertRaises(RuntimeError):
            _get_container_for_app_or_service(self.fake_docker_client,
                                              'app-c',
                                              raise_if_not_found=True)

    def test_exec_in_container_with_args(self):
        self.fake_docker_client.exec_create.return_value = {'Id': 'exec-id'}
        fake_container = {'Id': 'container-id'}
        _exec_in_container(self.fake_docker_client, fake_container, 'cp -r', '/tmp/a', '/tmp/b')
        self.fake_docker_client.exec_create.assert_called_once_with('container-id', 'cp -r /tmp/a /tmp/b')

    def test_exec_in_container_without_args(self):
        self.fake_docker_client.exec_create.return_value = {'Id': 'exec-id'}
        fake_container = {'Id': 'container-id'}
        _exec_in_container(self.fake_docker_client, fake_container, 'ls')
        self.fake_docker_client.exec_create.assert_called_once_with('container-id', 'ls')
<|endoftext|>


<commit_before>import __builtin__
from pytest import fail
from mock import MagicMock, patch, call
from pygit2 import (Repository as _Repository, GIT_CHECKOUT_SAFE_CREATE,
                    GIT_CHECKOUT_FORCE, GIT_BRANCH_REMOTE)

from .base import RepositoryBaseTest
from gitfs.utils import Repository

class TestRepository(RepositoryBaseTest):

    def setup(self):
        super(TestRepository, self).setup()

        def mock_super(*args, **kwargs):
            if args and issubclass(Repository, args[0]):
                return MagicMock()

            return original_super(*args, **kwargs)

        __builtin__.original_super = super
        __builtin__.super = mock_super

    def teardown(self):
        __builtin__.super = __builtin__.original_super
        del __builtin__.original_super

    def _get_repository(self):
        with patch.multiple('gitfs.utils.repository',
                            clone_repository=MagicMock()):
            repo = Repository.clone(self.remote_url, self.repo_path, self.branch)

        return repo

    def test_push(self):
        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)

        remote = "origin"
        branch = "master"

        repo = self._get_repository()
        repo.get_remote = mocked_get_remote
        repo.push(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.push("refs/heads/%s" % (branch))]

    def test_pull(self):
        remote = "origin"
        branch = "master"
        branch_target = 'test_target'

        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)
        mocked_returned_commit = MagicMock(name='the-commit')
        mocked_commit = MagicMock(return_value=mocked_returned_commit)
        mocked_branch = MagicMock()
        mocked_branch.target = branch_target
        mocked_lookup_branch = MagicMock(return_value=mocked_branch)
        mocked_merge = MagicMock()
        mocked_create_reference = MagicMock()
        mocked_checkout_head = MagicMock()
        mocked_clean_state_files = MagicMock()

        repo = self._get_repository()
        repo.lookup_branch = mocked_lookup_branch
        repo.merge = mocked_merge
        repo.create_reference = mocked_create_reference
        repo.commit = mocked_commit
        repo.checkout_head = mocked_checkout_head
        repo.get_remote = mocked_get_remote
        repo.clean_state_files = mocked_clean_state_files
        repo.pull(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.fetch()]
        mocked_lookup_branch.assert_called_once_with("%s/%s" % (remote, branch),
                                    GIT_BRANCH_REMOTE)
        mocked_merge.assert_called_once_with(branch_target)
        mocked_checkout_head.assert_called_once_with(GIT_CHECKOUT_FORCE)
        mocked_clean_state_files.assert_called_once_with()
        assert mocked_create_reference.call_count == 2
        mocked_create_reference_calls = [
            call('refs/heads/%s' % branch, branch_target, force=True),
            call('refs/heads/%s' % branch, mocked_returned_commit, force=True),
        ]
        mocked_create_reference.has_calls(mocked_create_reference_calls)

<commit_msg>Add test for 'get_clone'<commit_after>import __builtin__
from pytest import raises
from mock import MagicMock, Mock, PropertyMock, patch, call
from pygit2 import (GIT_CHECKOUT_SAFE_CREATE, GIT_CHECKOUT_FORCE,
                    GIT_BRANCH_REMOTE, Repository as _Repository)

from .base import RepositoryBaseTest
from gitfs.utils import Repository

from contextlib import contextmanager

@contextmanager
def patch_parent(klass):
    yield type(klass.__name__, (Mock,), dict(klass.__dict__))

class TestRepository(RepositoryBaseTest):

    def setup(self):
        super(TestRepository, self).setup()

        def mock_super(*args, **kwargs):
            if args and issubclass(Repository, args[0]):
                return MagicMock()

            return original_super(*args, **kwargs)

        __builtin__.original_super = super
        __builtin__.super = mock_super

    def teardown(self):
        __builtin__.super = __builtin__.original_super
        del __builtin__.original_super

    def _get_repository(self):
        with patch.multiple('gitfs.utils.repository',
                            _Repository=MagicMock(),
                            clone_repository=MagicMock()):
            repo = Repository.clone(self.remote_url, self.repo_path, self.branch)

        return repo

    def test_push(self):
        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)

        remote = "origin"
        branch = "master"

        repo = self._get_repository()
        repo.get_remote = mocked_get_remote
        repo.push(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.push("refs/heads/%s" % (branch))]

    def test_pull(self):
        remote = "origin"
        branch = "master"
        branch_target = 'test_target'

        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)
        mocked_returned_commit = MagicMock(name='the-commit')
        mocked_commit = MagicMock(return_value=mocked_returned_commit)
        mocked_branch = MagicMock()
        mocked_branch.target = branch_target
        mocked_lookup_branch = MagicMock(return_value=mocked_branch)
        mocked_merge = MagicMock()
        mocked_create_reference = MagicMock()
        mocked_checkout_head = MagicMock()
        mocked_clean_state_files = MagicMock()

        repo = self._get_repository()
        repo.lookup_branch = mocked_lookup_branch
        repo.merge = mocked_merge
        repo.create_reference = mocked_create_reference
        repo.commit = mocked_commit
        repo.checkout_head = mocked_checkout_head
        repo.get_remote = mocked_get_remote
        repo.clean_state_files = mocked_clean_state_files
        repo.pull(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.fetch()]
        mocked_lookup_branch.assert_called_once_with("%s/%s" % (remote, branch),
                                    GIT_BRANCH_REMOTE)
        mocked_merge.assert_called_once_with(branch_target)
        mocked_checkout_head.assert_called_once_with(GIT_CHECKOUT_FORCE)
        mocked_clean_state_files.assert_called_once_with()
        assert mocked_create_reference.call_count == 2
        mocked_create_reference_calls = [
            call('refs/heads/%s' % branch, branch_target, force=True),
            call('refs/heads/%s' % branch, mocked_returned_commit, force=True)]
        mocked_create_reference.has_calls(mocked_create_reference_calls)

    def test_get_remote(self):
        remote1 = MagicMock()
        remote1.name = 'remote1'
        remote2 = MagicMock()
        remote2.name = 'remote2'

        with patch('gitfs.utils.repository.Repository.remotes',
                   new_callable=PropertyMock) as mocked_remotes:
            mocked_remotes.return_value = [remote1, remote2]
            repo = self._get_repository()
            remote = repo.get_remote('remote2')
            assert remote.name == 'remote2'

            with raises(ValueError):
                remote = repo.get_remote('unavailable_remote')
<|endoftext|>


<commit_before><commit_msg>Fix one broken stratis-cli test<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python
from __future__ import print_function
import traceback

from parseobj import for_key, foreach, ObjParseError, ObjSyntaxError

heading_counter = 0

def heading(text):
    global heading_counter
    heading_counter += 1
    if heading_counter > 1:
        print("\n"*3, end=None)
    print("{}. {}".format(heading_counter, text))
    print()

###############################
# PARSING
heading("Parse object structures in a functional style.")

dutchman = {
    "name": "The Flying Dutchman",
    "roles": ["The Dutchman", "Senta", "Daland"]
}

def print_uppercase_count(name):
    print(len([c for c in name if c.isupper()]))

@for_key("name", print)
@for_key("roles", foreach(print_uppercase_count)(lambda x: None))
def parse_opera(opera):
    print("The opera has two attributes")

parse_opera(dutchman)

###############################
# ERROR HANDLING
heading("Get precise error messages what is wrong with the input.")
try:
    parse_opera({"name": "Das Rheingold"})
except ObjSyntaxError:
    traceback.print_exc()

heading("Get context for your error messages")

def raise_error(value):
    if value == 3:
        raise ValueError("Value is unusable!")

try:
    foreach([1, 2, 3, 4], raise_error)
except ValueError, e:
    traceback.print_exc()

###############################
# Get the grammar.
heading("Get a pseudo-grammar for the expected input")

parse_opera.print_grammar()

###############################
# Generate example input.
<commit_msg>Removed ObjParseError, because the native exceptions are more useful to the user, both when handling and when debugging (now also in readme.py)<commit_after>#!/usr/bin/python
from __future__ import print_function
import traceback

from parseobj import for_key, foreach, ObjSyntaxError

heading_counter = 0

def heading(text):
    global heading_counter
    heading_counter += 1
    if heading_counter > 1:
        print("\n"*3, end=None)
    print("{}. {}".format(heading_counter, text))
    print()

###############################
# PARSING
heading("Parse object structures in a functional style.")

dutchman = {
    "name": "The Flying Dutchman",
    "roles": ["The Dutchman", "Senta", "Daland"]
}

def print_uppercase_count(name):
    print(len([c for c in name if c.isupper()]))

@for_key("name", print)
@for_key("roles", foreach(print_uppercase_count)(lambda x: None))
def parse_opera(opera):
    print("The opera has two attributes")

parse_opera(dutchman)

###############################
# ERROR HANDLING
heading("Get precise error messages what is wrong with the input.")
try:
    parse_opera({"name": "Das Rheingold"})
except ObjSyntaxError:
    traceback.print_exc()

heading("Get context for your error messages")

def raise_error(value):
    if value == 3:
        raise ValueError("Value is unusable!")

try:
    foreach([1, 2, 3, 4], raise_error)
except ValueError, e:
    traceback.print_exc()

###############################
# Get the grammar.
heading("Get a pseudo-grammar for the expected input")

parse_opera.print_grammar()

###############################
# Generate example input.
<|endoftext|>


<commit_before>"""
sentry.coreapi
~~~~~~~~~~~~~~

:copyright: (c) 2010-2014 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
# TODO: We should make the API a class, and UDP/HTTP just inherit from it
#       This will make it so we can more easily control logging with various
#       metadata (rather than generic log messages which aren't useful).
from __future__ import absolute_import, print_function

import base64
import logging
import six
import uuid
import zlib

from datetime import datetime, timedelta
from django.utils.crypto import constant_time_compare
from django.utils.encoding import smart_str
from gzip import GzipFile

from sentry.app import cache, env
from sentry.constants import (
    DEFAULT_LOG_LEVEL, LOG_LEVELS, MAX_TAG_VALUE_LENGTH,
    MAX_TAG_KEY_LENGTH)
from sentry.exceptions import InvalidTimestamp
from sentry.interfaces.base import get_interface
from sentry.models import Project, ProjectKey
from sentry.tasks.store import preprocess_event
from sentry.utils import is_float, json
from sentry.utils.auth import parse_auth_header
from sentry.utils.compat import StringIO
from sentry.utils.strings import decompress

logger = logging.getLogger('sentry.coreapi')

LOG_LEVEL_REVERSE_MAP = dict((v, k) for k, v in LOG_LEVELS.iteritems())

RESERVED_FIELDS = (
    'project',
    'event_id',
    'message',
    'checksum',
    'culprit',
    'level',
    'time_spent',
    'logger',
    'server_name',
    'site',
    'timestamp',
    'extra',
    'modules',
    'tags',
    'platform',
    'release',
)

class APIError(Exception):
    http_status = 400
    msg = 'Invalid request'

    def __init__(self, msg=None):
        if msg:
            self.msg = msg

    def __str__(self):
        return self.msg or ''

class APIUnauthorized(APIError):
    http_status = 401
    msg = 'Unauthorized'

class APIForbidden(APIError):
    http_status = 403

class APITimestampExpired(APIError):
    http_status = 410

class APIRateLimited(APIError):
    http_status = 429
    msg = 'Creation of this event was denied due to rate limiting.'

    def __init__(self, retry_after=None):
        self.retry_after = retry_after

def client_metadata(client=None, project=None, exception=None, tags=None, extra=None):
    if not extra:
        extra = {}
    if not tags:
        tags = {}

    extra['client'] = client
    extra['request'] = env.request
    extra['tags'] = tags
    if project:
        extra['project_slug'] = project.slug
        extra['project_id'] = project.id
        if project.team:
            extra['team_slug'] = project.team.slug
            extra['team_id'] = project.team.id
        if project.organization:
            extra['organization_slug'] = project.organization.slug
            extra['organization_id'] = project.organization.id

    tags['client'] = client
    if exception:
        tags['exc_type'] = type(exception).__name__
    if project and project.organization:
        tags['project'] = '%s/%s' % (project.organization.slug, project.slug)

    result = {'extra': extra}
    if exception:
        result['exc_info'] = True
    return result

def extract_auth_vars(request):
    if request.META.get('HTTP_X_SENTRY_AUTH', '').startswith('Sentry'):
        return parse_auth_header(request.META['HTTP_X_SENTRY_AUTH'])
    elif request.META.get('HTTP_AUTHORIZATION', '').startswith('Sentry'):
        return parse_auth_header(request.META['HTTP_AUTHORIZATION'])
    else:
        return dict(
            (k, request.GET[k])
            for k in request.GET.iterkeys()
            if k.startswith('sentry_')
        )

def project_from_auth_vars(auth_vars):
    api_key = auth_vars.get('sentry_key')
    if not api_key:
        raise APIForbidden('Invalid api key')
    try:
        pk = ProjectKey.objects.get_from_cache(public_key=api_key)
    except ProjectKey.DoesNotExist:
        raise APIForbidden('Invalid api key')

    if not constant_time_compare(pk.secret_key, auth_vars.get('sentry_secret', pk.secret_key)):
        raise APIForbidden('Invalid api key')

    if not pk.is_active:
        raise APIForbidden('API key is disabled')

    if not pk.roles.store:
        raise APIForbidden('Key does not allow event storage access')

    project = Project.objects.get_from_cache(pk=pk.project_id)

    return project, pk.user

def decompress_deflate(encoded_data):
    try:
        return zlib.decompress(encoded_data)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def decompress_gzip(encoded_data):
    try:
        fp = StringIO(encoded_data)
        try:
            f = GzipFile(fileobj=fp)
            return f.read()
        finally:
            f.close()
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def decode_and_decompress_data(encoded_data):
    try:
        try:
            return decompress(encoded_data)
        except zlib.error:
            return base64.b64decode(encoded_data)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def safely_load_json_string(json_string):
    try:
        obj = json.loads(json_string)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data reconstructing object (%s, %s)' % (
            e.__class__.__name__, e))

    # XXX: ensure keys are coerced to strings
    return dict((smart_str(k), v) for k, v in obj.iteritems())

def process_data_timestamp(data, current_datetime=None):
    if not data['timestamp']:
        del data['timestamp']
        return data
    elif is_float(data['timestamp']):
        try:
            data['timestamp'] = datetime.fromtimestamp(float(data['timestamp']))
        except Exception:
            raise InvalidTimestamp('Invalid value for timestamp: %r' % data['timestamp'])
    elif not isinstance(data['timestamp'], datetime):
        if '.' in data['timestamp']:
            format = '%Y-%m-%dT%H:%M:%S.%f'
        else:
            format = '%Y-%m-%dT%H:%M:%S'
        if 'Z' in data['timestamp']:
            # support UTC market, but not other timestamps
            format += 'Z'
        try:
            data['timestamp'] = datetime.strptime(data['timestamp'], format)
        except Exception:
            raise InvalidTimestamp('Invalid value for timestamp: %r' % data['timestamp'])

    if current_datetime is None:
        current_datetime = datetime.now()

    if data['timestamp'] > current_datetime + timedelta(minutes=1):
        raise InvalidTimestamp('Invalid value for timestamp (in future): %r' % data['timestamp'])

    if data['timestamp'] < current_datetime - timedelta(days=30):
        raise InvalidTimestamp('Invalid value for timestamp (too old): %r' % data['timestamp'])

    data['timestamp'] = float(data['timestamp'].strftime('%s'))

    return data

def validate_data(project, data, client=None):
    # TODO(dcramer): move project out of the data packet
    data['project'] = project.id

    if not data.get('message'):
        data['message'] = '<no message value>'
    elif not isinstance(data['message'], six.string_types):
        raise APIError('Invalid value for message')

    if data.get('culprit'):
        if not isinstance(data['culprit'], six.string_types):
            raise APIError('Invalid value for culprit')

    if not data.get('event_id'):
        data['event_id'] = uuid.uuid4().hex
    elif not isinstance(data['event_id'], six.string_types):
        raise APIError('Invalid value for event_id')
    if len(data['event_id']) > 32:
        logger.info(
            'Discarded value for event_id due to length (%d chars)',
            len(data['event_id']), **client_metadata(client, project))
        data['event_id'] = uuid.uuid4().hex

    if 'timestamp' in data:
        try:
            process_data_timestamp(data)
        except InvalidTimestamp as e:
            # Log the error, remove the timestamp, and continue
            logger.info(
                'Discarded invalid value for timestamp: %r', data['timestamp'],
                **client_metadata(client, project, exception=e))
            del data['timestamp']

    if data.get('modules') and type(data['modules']) != dict:
        logger.info(
            'Discarded invalid type for modules: %s',
            type(data['modules']), **client_metadata(client, project))
        del data['modules']

    if data.get('extra') is not None and type(data['extra']) != dict:
        logger.info(
            'Discarded invalid type for extra: %s',
            type(data['extra']), **client_metadata(client, project))
        del data['extra']

    if data.get('tags') is not None:
        if type(data['tags']) == dict:
            data['tags'] = data['tags'].items()
        elif not isinstance(data['tags'], (list, tuple)):
            logger.info(
                'Discarded invalid type for tags: %s',
                type(data['tags']), **client_metadata(client, project))
            del data['tags']

    if data.get('tags'):
        # remove any values which are over 32 characters
        tags = []
        for pair in data['tags']:
            try:
                k, v = pair
            except ValueError:
                logger.info('Discarded invalid tag value: %r',
                            pair, **client_metadata(client, project))
                continue

            if not isinstance(k, six.string_types):
                try:
                    k = six.text_type(k)
                except Exception:
                    logger.info('Discarded invalid tag key: %r',
                                type(k), **client_metadata(client, project))
                    continue

            if not isinstance(v, six.string_types):
                try:
                    v = six.text_type(v)
                except Exception:
                    logger.info('Discarded invalid tag value: %s=%r',
                                k, type(v), **client_metadata(client, project))
                    continue
            if len(k) > MAX_TAG_KEY_LENGTH or len(v) > MAX_TAG_VALUE_LENGTH:
                logger.info('Discarded invalid tag: %s=%s',
                            k, v, **client_metadata(client, project))
                continue
            tags.append((k, v))
        data['tags'] = tags

    for k in data.keys():
        if k in RESERVED_FIELDS:
            continue

        value = data.pop(k)

        if not value:
            logger.info(
                'Ignored empty interface value: %s', k,
                **client_metadata(client, project))
            continue

        try:
            interface = get_interface(k)
        except ValueError:
            logger.info(
                'Ignored unknown attribute: %s', k,
                **client_metadata(client, project))
            continue

        if type(value) != dict:
            # HACK(dcramer): the exception interface supports a list as the
            # value. We should change this in a new protocol version.
            if type(value) in (list, tuple):
                value = {'values': value}
            else:
                logger.info(
                    'Invalid parameters for value: %s', k,
                    type(value), **client_metadata(client, project))
                continue

        try:
            inst = interface.to_python(value)
            data[inst.get_path()] = inst.to_json()
        except Exception as e:
            if isinstance(e, AssertionError):
                log = logger.info
            else:
                log = logger.error
            log('Discarded invalid value for interface: %s', k,
                **client_metadata(client, project, exception=e, extra={'value': value}))

    level = data.get('level') or DEFAULT_LOG_LEVEL
    if isinstance(level, six.string_types) and not level.isdigit():
        # assume it's something like 'warning'
        try:
            data['level'] = LOG_LEVEL_REVERSE_MAP[level]
        except KeyError as e:
            logger.info(
                'Discarded invalid logger value: %s', level,
                **client_metadata(client, project, exception=e))
            data['level'] = LOG_LEVEL_REVERSE_MAP.get(
                DEFAULT_LOG_LEVEL, DEFAULT_LOG_LEVEL)

    return data

def ensure_does_not_have_ip(data):
    if 'sentry.interfaces.Http' in data:
        if 'env' in data['sentry.interfaces.Http']:
            data['sentry.interfaces.Http']['env'].pop('REMOTE_ADDR', None)

    if 'sentry.interfaces.User' in data:
        data['sentry.interfaces.User'].pop('ip_address', None)

def ensure_has_ip(data, ip_address):
    if data.get('sentry.interfaces.Http', {}).get('env', {}).get('REMOTE_ADDR'):
        return

    if data.get('sentry.interfaces.User', {}).get('ip_address'):
        return

    data.setdefault('sentry.interfaces.User', {})['ip_address'] = ip_address

def insert_data_to_database(data):
    cache_key = 'e:{0}'.format(data['event_id'])
    cache.set(cache_key, data, timeout=3600)
    preprocess_event.delay(cache_key=cache_key)
<commit_msg>Ensure no possible event ID conflicts<commit_after>"""
sentry.coreapi
~~~~~~~~~~~~~~

:copyright: (c) 2010-2014 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
# TODO: We should make the API a class, and UDP/HTTP just inherit from it
#       This will make it so we can more easily control logging with various
#       metadata (rather than generic log messages which aren't useful).
from __future__ import absolute_import, print_function

import base64
import logging
import six
import uuid
import zlib

from datetime import datetime, timedelta
from django.utils.crypto import constant_time_compare
from django.utils.encoding import smart_str
from gzip import GzipFile

from sentry.app import cache, env
from sentry.constants import (
    DEFAULT_LOG_LEVEL, LOG_LEVELS, MAX_TAG_VALUE_LENGTH,
    MAX_TAG_KEY_LENGTH)
from sentry.exceptions import InvalidTimestamp
from sentry.interfaces.base import get_interface
from sentry.models import Project, ProjectKey
from sentry.tasks.store import preprocess_event
from sentry.utils import is_float, json
from sentry.utils.auth import parse_auth_header
from sentry.utils.compat import StringIO
from sentry.utils.strings import decompress

logger = logging.getLogger('sentry.coreapi')

LOG_LEVEL_REVERSE_MAP = dict((v, k) for k, v in LOG_LEVELS.iteritems())

RESERVED_FIELDS = (
    'project',
    'event_id',
    'message',
    'checksum',
    'culprit',
    'level',
    'time_spent',
    'logger',
    'server_name',
    'site',
    'timestamp',
    'extra',
    'modules',
    'tags',
    'platform',
    'release',
)

class APIError(Exception):
    http_status = 400
    msg = 'Invalid request'

    def __init__(self, msg=None):
        if msg:
            self.msg = msg

    def __str__(self):
        return self.msg or ''

class APIUnauthorized(APIError):
    http_status = 401
    msg = 'Unauthorized'

class APIForbidden(APIError):
    http_status = 403

class APITimestampExpired(APIError):
    http_status = 410

class APIRateLimited(APIError):
    http_status = 429
    msg = 'Creation of this event was denied due to rate limiting.'

    def __init__(self, retry_after=None):
        self.retry_after = retry_after

def client_metadata(client=None, project=None, exception=None, tags=None, extra=None):
    if not extra:
        extra = {}
    if not tags:
        tags = {}

    extra['client'] = client
    extra['request'] = env.request
    extra['tags'] = tags
    if project:
        extra['project_slug'] = project.slug
        extra['project_id'] = project.id
        if project.team:
            extra['team_slug'] = project.team.slug
            extra['team_id'] = project.team.id
        if project.organization:
            extra['organization_slug'] = project.organization.slug
            extra['organization_id'] = project.organization.id

    tags['client'] = client
    if exception:
        tags['exc_type'] = type(exception).__name__
    if project and project.organization:
        tags['project'] = '%s/%s' % (project.organization.slug, project.slug)

    result = {'extra': extra}
    if exception:
        result['exc_info'] = True
    return result

def extract_auth_vars(request):
    if request.META.get('HTTP_X_SENTRY_AUTH', '').startswith('Sentry'):
        return parse_auth_header(request.META['HTTP_X_SENTRY_AUTH'])
    elif request.META.get('HTTP_AUTHORIZATION', '').startswith('Sentry'):
        return parse_auth_header(request.META['HTTP_AUTHORIZATION'])
    else:
        return dict(
            (k, request.GET[k])
            for k in request.GET.iterkeys()
            if k.startswith('sentry_')
        )

def project_from_auth_vars(auth_vars):
    api_key = auth_vars.get('sentry_key')
    if not api_key:
        raise APIForbidden('Invalid api key')
    try:
        pk = ProjectKey.objects.get_from_cache(public_key=api_key)
    except ProjectKey.DoesNotExist:
        raise APIForbidden('Invalid api key')

    if not constant_time_compare(pk.secret_key, auth_vars.get('sentry_secret', pk.secret_key)):
        raise APIForbidden('Invalid api key')

    if not pk.is_active:
        raise APIForbidden('API key is disabled')

    if not pk.roles.store:
        raise APIForbidden('Key does not allow event storage access')

    project = Project.objects.get_from_cache(pk=pk.project_id)

    return project, pk.user

def decompress_deflate(encoded_data):
    try:
        return zlib.decompress(encoded_data)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def decompress_gzip(encoded_data):
    try:
        fp = StringIO(encoded_data)
        try:
            f = GzipFile(fileobj=fp)
            return f.read()
        finally:
            f.close()
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def decode_and_decompress_data(encoded_data):
    try:
        try:
            return decompress(encoded_data)
        except zlib.error:
            return base64.b64decode(encoded_data)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data decoding request (%s, %s)' % (
            e.__class__.__name__, e))

def safely_load_json_string(json_string):
    try:
        obj = json.loads(json_string)
    except Exception as e:
        # This error should be caught as it suggests that there's a
        # bug somewhere in the client's code.
        logger.info(e, **client_metadata(exception=e))
        raise APIForbidden('Bad data reconstructing object (%s, %s)' % (
            e.__class__.__name__, e))

    # XXX: ensure keys are coerced to strings
    return dict((smart_str(k), v) for k, v in obj.iteritems())

def process_data_timestamp(data, current_datetime=None):
    if not data['timestamp']:
        del data['timestamp']
        return data
    elif is_float(data['timestamp']):
        try:
            data['timestamp'] = datetime.fromtimestamp(float(data['timestamp']))
        except Exception:
            raise InvalidTimestamp('Invalid value for timestamp: %r' % data['timestamp'])
    elif not isinstance(data['timestamp'], datetime):
        if '.' in data['timestamp']:
            format = '%Y-%m-%dT%H:%M:%S.%f'
        else:
            format = '%Y-%m-%dT%H:%M:%S'
        if 'Z' in data['timestamp']:
            # support UTC market, but not other timestamps
            format += 'Z'
        try:
            data['timestamp'] = datetime.strptime(data['timestamp'], format)
        except Exception:
            raise InvalidTimestamp('Invalid value for timestamp: %r' % data['timestamp'])

    if current_datetime is None:
        current_datetime = datetime.now()

    if data['timestamp'] > current_datetime + timedelta(minutes=1):
        raise InvalidTimestamp('Invalid value for timestamp (in future): %r' % data['timestamp'])

    if data['timestamp'] < current_datetime - timedelta(days=30):
        raise InvalidTimestamp('Invalid value for timestamp (too old): %r' % data['timestamp'])

    data['timestamp'] = float(data['timestamp'].strftime('%s'))

    return data

def validate_data(project, data, client=None):
    # TODO(dcramer): move project out of the data packet
    data['project'] = project.id

    if not data.get('message'):
        data['message'] = '<no message value>'
    elif not isinstance(data['message'], six.string_types):
        raise APIError('Invalid value for message')

    if data.get('culprit'):
        if not isinstance(data['culprit'], six.string_types):
            raise APIError('Invalid value for culprit')

    if not data.get('event_id'):
        data['event_id'] = uuid.uuid4().hex
    elif not isinstance(data['event_id'], six.string_types):
        raise APIError('Invalid value for event_id')
    if len(data['event_id']) > 32:
        logger.info(
            'Discarded value for event_id due to length (%d chars)',
            len(data['event_id']), **client_metadata(client, project))
        data['event_id'] = uuid.uuid4().hex

    if 'timestamp' in data:
        try:
            process_data_timestamp(data)
        except InvalidTimestamp as e:
            # Log the error, remove the timestamp, and continue
            logger.info(
                'Discarded invalid value for timestamp: %r', data['timestamp'],
                **client_metadata(client, project, exception=e))
            del data['timestamp']

    if data.get('modules') and type(data['modules']) != dict:
        logger.info(
            'Discarded invalid type for modules: %s',
            type(data['modules']), **client_metadata(client, project))
        del data['modules']

    if data.get('extra') is not None and type(data['extra']) != dict:
        logger.info(
            'Discarded invalid type for extra: %s',
            type(data['extra']), **client_metadata(client, project))
        del data['extra']

    if data.get('tags') is not None:
        if type(data['tags']) == dict:
            data['tags'] = data['tags'].items()
        elif not isinstance(data['tags'], (list, tuple)):
            logger.info(
                'Discarded invalid type for tags: %s',
                type(data['tags']), **client_metadata(client, project))
            del data['tags']

    if data.get('tags'):
        # remove any values which are over 32 characters
        tags = []
        for pair in data['tags']:
            try:
                k, v = pair
            except ValueError:
                logger.info('Discarded invalid tag value: %r',
                            pair, **client_metadata(client, project))
                continue

            if not isinstance(k, six.string_types):
                try:
                    k = six.text_type(k)
                except Exception:
                    logger.info('Discarded invalid tag key: %r',
                                type(k), **client_metadata(client, project))
                    continue

            if not isinstance(v, six.string_types):
                try:
                    v = six.text_type(v)
                except Exception:
                    logger.info('Discarded invalid tag value: %s=%r',
                                k, type(v), **client_metadata(client, project))
                    continue
            if len(k) > MAX_TAG_KEY_LENGTH or len(v) > MAX_TAG_VALUE_LENGTH:
                logger.info('Discarded invalid tag: %s=%s',
                            k, v, **client_metadata(client, project))
                continue
            tags.append((k, v))
        data['tags'] = tags

    for k in data.keys():
        if k in RESERVED_FIELDS:
            continue

        value = data.pop(k)

        if not value:
            logger.info(
                'Ignored empty interface value: %s', k,
                **client_metadata(client, project))
            continue

        try:
            interface = get_interface(k)
        except ValueError:
            logger.info(
                'Ignored unknown attribute: %s', k,
                **client_metadata(client, project))
            continue

        if type(value) != dict:
            # HACK(dcramer): the exception interface supports a list as the
            # value. We should change this in a new protocol version.
            if type(value) in (list, tuple):
                value = {'values': value}
            else:
                logger.info(
                    'Invalid parameters for value: %s', k,
                    type(value), **client_metadata(client, project))
                continue

        try:
            inst = interface.to_python(value)
            data[inst.get_path()] = inst.to_json()
        except Exception as e:
            if isinstance(e, AssertionError):
                log = logger.info
            else:
                log = logger.error
            log('Discarded invalid value for interface: %s', k,
                **client_metadata(client, project, exception=e, extra={'value': value}))

    level = data.get('level') or DEFAULT_LOG_LEVEL
    if isinstance(level, six.string_types) and not level.isdigit():
        # assume it's something like 'warning'
        try:
            data['level'] = LOG_LEVEL_REVERSE_MAP[level]
        except KeyError as e:
            logger.info(
                'Discarded invalid logger value: %s', level,
                **client_metadata(client, project, exception=e))
            data['level'] = LOG_LEVEL_REVERSE_MAP.get(
                DEFAULT_LOG_LEVEL, DEFAULT_LOG_LEVEL)

    return data

def ensure_does_not_have_ip(data):
    if 'sentry.interfaces.Http' in data:
        if 'env' in data['sentry.interfaces.Http']:
            data['sentry.interfaces.Http']['env'].pop('REMOTE_ADDR', None)

    if 'sentry.interfaces.User' in data:
        data['sentry.interfaces.User'].pop('ip_address', None)

def ensure_has_ip(data, ip_address):
    if data.get('sentry.interfaces.Http', {}).get('env', {}).get('REMOTE_ADDR'):
        return

    if data.get('sentry.interfaces.User', {}).get('ip_address'):
        return

    data.setdefault('sentry.interfaces.User', {})['ip_address'] = ip_address

def insert_data_to_database(data):
    cache_key = 'e:{1}:{0}'.format(data['project'], data['event_id'])
    cache.set(cache_key, data, timeout=3600)
    preprocess_event.delay(cache_key=cache_key)
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
from random import randint
import requests
import asyncio
from .utils.dataIO import dataIO, fileIO
import time
import random

lastTag = '0'
creditIcon = "https://i.imgur.com/TP8GXZb.png"
credits = "Bot by GR8 | Titan"

class tournament:
	"""tournament!"""

	def __init__(self, bot):
		self.bot = bot
		self.auth = dataIO.load_json('cogs/auth.json')

	def getAuth(self):
		return {"auth" : self.auth['token']}

	# Converts maxPlayers to Cards
	def getCards(self, maxPlayers):
		if maxPlayers == 50: return 25
		if maxPlayers == 100: return 100
		if maxPlayers == 200: return 400
		if maxPlayers == 1000: return 2000

	# Converts maxPlayers to Cards
	def getCoins(self, maxPlayers):
		if maxPlayers == 50: return 175
		if maxPlayers == 100: return 700
		if maxPlayers == 200: return 2800
		if maxPlayers == 1000: return 14000

	# Converts seconds to time
	def sec2tme(self, sec):
		m, s = divmod(sec, 60)
		h, m = divmod(m, 60)

		if h is 0:
			if m is 0:
				return "{} seconds".format(s)
			else:
				return "{} minutes, {} secs".format(m,s)
		else:
			return "{} hour, {} mins".format(h,m)

	# Returns a list with tournaments
	async def getTopTourney(self):

		global lastTag
		try:
			openTourney = requests.get('https://api.royaleapi.com/tournaments/open', headers=self.getAuth(), timeout=10).json()
		except:
			return None

		for tourney in openTourney:

			tag = tourney['tag']
			joined = tourney['playerCount']
			maxplayers = tourney['maxCapacity']

			if ((maxplayers > 50) and ((joined + 4) < maxplayers) and (tag != lastTag)):

				try:
					tourneyAPI = requests.get('https://api.royaleapi.com/tournaments/{}'.format(tag), headers=self.getAuth(), timeout=10).json()
					joined = tourneyAPI['playerCount']
					maxplayers = tourneyAPI['maxCapacity']
				except:
					return None

				if ((maxplayers > 50) and ((joined + 4) < maxplayers) and  (tourneyAPI['status'] != "ended") and (tourneyAPI['type'] != "passwordProtected")):
					tourneyAPI['tag'] = tag

					return tourneyAPI

		return None

	# Returns a list with tournaments
	async def getRandomTourney(self):

		try:
			openTourney = requests.get('https://api.royaleapi.com/tournaments/open', headers=self.getAuth(), timeout=10).json()
		except:
			return None

		#random.shuffle(openTourney)
		for tourney in openTourney:

			tag = tourney['tag']
			joined = tourney['playerCount']
			maxplayers = tourney['maxCapacity']

			if ((joined + 1) < maxplayers):

				try:
					tourneyAPI = requests.get('https://api.royaleapi.com/tournaments/{}'.format(tag), headers=self.getAuth(), timeout=10).json()
					joined = tourneyAPI['playerCount']
					maxplayers = tourneyAPI['maxCapacity']
				except:
					return None

				if ((joined < maxplayers) and  (tourneyAPI['status'] != "ended") and (tourneyAPI['type'] != "passwordProtected")):
					tourneyAPI['tag'] = tag

					return tourneyAPI

		return None

	# checks for a tourney every 5 minutes
	async def checkTourney(self):
		server = [x.id for x in self.bot.servers if x.id == "374596069989810176"][0]
		role_name = "Tournaments"
		if role_name is not None:
			tour_role = discord.utils.get(server.roles, name=role_name)
			if tour_role is None:
				await self.bot.create_role(server, name=role_name)
				tour_role = discord.utils.get(server.roles, name=role_name)

		while self is self.bot.get_cog("tournament"):
			tourneydata = await self.getTopTourney()
			if tourneydata is not None:
				maxCapacity = tourneydata['maxCapacity']
				cards = self.getCards(maxCapacity)
				coins = self.getCoins(maxCapacity)

				embed=discord.Embed(content="New {}. Type ``!r tournaments`` to turn on tournament notifications.".format(tour_role.mention), title="Click this link to join the Tournament in Clash Royale!", url="https://legendclans.com/tournaments?id={}".format(tourneydata['tag']), color=0xFAA61A)
				embed.set_thumbnail(url='https://statsroyale.com/images/tournament.png')

				embed.set_author(name=tourneydata['name']+" (#"+tourneydata['tag']+")")

				embed.add_field(name="Players", value=str(tourneydata['playerCount']) + "/" + str(maxCapacity), inline=True)
				embed.add_field(name="Status", value=tourneydata['status'].title(), inline=True)

				if tourneydata['status'] != "inProgress":
					startTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration']) - int(time.time()))
					embed.add_field(name="Starts In", value=startTime, inline=True)

				endTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration'] + tourneydata['duration']) - int(time.time()))
				embed.add_field(name="Ends In", value=endTime, inline=True)

				embed.add_field(name="Top prize", value="<:tournamentcards:380832770454192140> " + str(cards) + "	 <:coin:380832316932489268> " +  str(coins), inline=True)
				embed.set_footer(text=credits, icon_url=creditIcon)

				await self.bot.edit_role(server, tour_role, mentionable=True)
				await self.bot.send_message(discord.Object(id='374597050530136064'), embed=embed) # Family
				await self.bot.edit_role(server, tour_role, mentionable=False)
				await asyncio.sleep(900)
			await asyncio.sleep(120)

	@commands.command()
	async def tourney(self):
		""" Get a open tournament"""

		await self.bot.type()

		tourneydata = await self.getRandomTourney()

		if tourneydata is not None:
			maxCapacity = tourneydata['maxCapacity']
			cards = self.getCards(maxCapacity)
			coins = self.getCoins(maxCapacity)

			embed=discord.Embed(title="Click this link to join the Tournament in Clash Royale!", url="https://legendclans.com/tournaments?id={}".format(tourneydata['tag']), color=0xFAA61A)
			embed.set_thumbnail(url='https://statsroyale.com/images/tournament.png')

			embed.set_author(name=tourneydata['name']+" (#"+tourneydata['tag']+")")

			embed.add_field(name="Players", value=str(tourneydata['playerCount']) + "/" + str(maxCapacity), inline=True)
			embed.add_field(name="Status", value=tourneydata['status'].title(), inline=True)

			if tourneydata['status'] != "inProgress":
				startTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration']) - int(time.time()))
				embed.add_field(name="Starts In", value=startTime, inline=True)

			endTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration'] + tourneydata['duration']) - int(time.time()))
			embed.add_field(name="Ends In", value=endTime, inline=True)

			embed.add_field(name="Top prize", value="<:tournamentcards:380832770454192140> " + str(cards) + "	 <:coin:380832316932489268> " +  str(coins), inline=True)
			embed.set_footer(text=credits, icon_url=creditIcon)
			await self.bot.say(embed=embed)
		else:
			await self.bot.say("Found nothing, please try again after a few minutes!")
			return

def check_files():
	f = "cogs/auth.json"
	if not fileIO(f, "check"):
		print("enter your RoyaleAPI token in auth.json...")
		fileIO(f, "save", {"token" : "enter your RoyaleAPI token here!"})

def check_auth():
	c = dataIO.load_json('cogs/auth.json')
	if 'token' not in c:
		c['token'] = ""
	dataIO.save_json('cogs/auth.json', c)

def setup(bot):
	n = tournament(bot)
	check_files()
	check_auth()
	loop = asyncio.get_event_loop()
	loop.create_task(n.checkTourney())
	bot.add_cog(n)<commit_msg>remove id<commit_after>import discord
from discord.ext import commands
from random import randint
import requests
import asyncio
from .utils.dataIO import dataIO, fileIO
import time
import random

lastTag = '0'
creditIcon = "https://i.imgur.com/TP8GXZb.png"
credits = "Bot by GR8 | Titan"

class tournament:
	"""tournament!"""

	def __init__(self, bot):
		self.bot = bot
		self.auth = dataIO.load_json('cogs/auth.json')

	def getAuth(self):
		return {"auth" : self.auth['token']}

	# Converts maxPlayers to Cards
	def getCards(self, maxPlayers):
		if maxPlayers == 50: return 25
		if maxPlayers == 100: return 100
		if maxPlayers == 200: return 400
		if maxPlayers == 1000: return 2000

	# Converts maxPlayers to Cards
	def getCoins(self, maxPlayers):
		if maxPlayers == 50: return 175
		if maxPlayers == 100: return 700
		if maxPlayers == 200: return 2800
		if maxPlayers == 1000: return 14000

	# Converts seconds to time
	def sec2tme(self, sec):
		m, s = divmod(sec, 60)
		h, m = divmod(m, 60)

		if h is 0:
			if m is 0:
				return "{} seconds".format(s)
			else:
				return "{} minutes, {} secs".format(m,s)
		else:
			return "{} hour, {} mins".format(h,m)

	# Returns a list with tournaments
	async def getTopTourney(self):

		global lastTag
		try:
			openTourney = requests.get('https://api.royaleapi.com/tournaments/open', headers=self.getAuth(), timeout=10).json()
		except:
			return None

		for tourney in openTourney:

			tag = tourney['tag']
			joined = tourney['playerCount']
			maxplayers = tourney['maxCapacity']

			if ((maxplayers > 50) and ((joined + 4) < maxplayers) and (tag != lastTag)):

				try:
					tourneyAPI = requests.get('https://api.royaleapi.com/tournaments/{}'.format(tag), headers=self.getAuth(), timeout=10).json()
					joined = tourneyAPI['playerCount']
					maxplayers = tourneyAPI['maxCapacity']
				except:
					return None

				if ((maxplayers > 50) and ((joined + 4) < maxplayers) and  (tourneyAPI['status'] != "ended") and (tourneyAPI['type'] != "passwordProtected")):
					tourneyAPI['tag'] = tag

					return tourneyAPI

		return None

	# Returns a list with tournaments
	async def getRandomTourney(self):

		try:
			openTourney = requests.get('https://api.royaleapi.com/tournaments/open', headers=self.getAuth(), timeout=10).json()
		except:
			return None

		#random.shuffle(openTourney)
		for tourney in openTourney:

			tag = tourney['tag']
			joined = tourney['playerCount']
			maxplayers = tourney['maxCapacity']

			if ((joined + 1) < maxplayers):

				try:
					tourneyAPI = requests.get('https://api.royaleapi.com/tournaments/{}'.format(tag), headers=self.getAuth(), timeout=10).json()
					joined = tourneyAPI['playerCount']
					maxplayers = tourneyAPI['maxCapacity']
				except:
					return None

				if ((joined < maxplayers) and  (tourneyAPI['status'] != "ended") and (tourneyAPI['type'] != "passwordProtected")):
					tourneyAPI['tag'] = tag

					return tourneyAPI

		return None

	# checks for a tourney every 5 minutes
	async def checkTourney(self):
		server = [x for x in self.bot.servers if x.id == "374596069989810176"][0]
		role_name = "Tournaments"
		if role_name is not None:
			tour_role = discord.utils.get(server.roles, name=role_name)
			if tour_role is None:
				await self.bot.create_role(server, name=role_name)
				tour_role = discord.utils.get(server.roles, name=role_name)

		while self is self.bot.get_cog("tournament"):
			tourneydata = await self.getTopTourney()
			if tourneydata is not None:
				maxCapacity = tourneydata['maxCapacity']
				cards = self.getCards(maxCapacity)
				coins = self.getCoins(maxCapacity)

				embed=discord.Embed(content="New {}. Type ``!r tournaments`` to turn on tournament notifications.".format(tour_role.mention), title="Click this link to join the Tournament in Clash Royale!", url="https://legendclans.com/tournaments?id={}".format(tourneydata['tag']), color=0xFAA61A)
				embed.set_thumbnail(url='https://statsroyale.com/images/tournament.png')

				embed.set_author(name=tourneydata['name']+" (#"+tourneydata['tag']+")")

				embed.add_field(name="Players", value=str(tourneydata['playerCount']) + "/" + str(maxCapacity), inline=True)
				embed.add_field(name="Status", value=tourneydata['status'].title(), inline=True)

				if tourneydata['status'] != "inProgress":
					startTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration']) - int(time.time()))
					embed.add_field(name="Starts In", value=startTime, inline=True)

				endTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration'] + tourneydata['duration']) - int(time.time()))
				embed.add_field(name="Ends In", value=endTime, inline=True)

				embed.add_field(name="Top prize", value="<:tournamentcards:380832770454192140> " + str(cards) + "	 <:coin:380832316932489268> " +  str(coins), inline=True)
				embed.set_footer(text=credits, icon_url=creditIcon)

				await self.bot.edit_role(server, tour_role, mentionable=True)
				await self.bot.send_message(discord.Object(id='374597050530136064'), embed=embed) # Family
				await self.bot.edit_role(server, tour_role, mentionable=False)
				await asyncio.sleep(900)
			await asyncio.sleep(120)

	@commands.command()
	async def tourney(self):
		""" Get a open tournament"""

		await self.bot.type()

		tourneydata = await self.getRandomTourney()

		if tourneydata is not None:
			maxCapacity = tourneydata['maxCapacity']
			cards = self.getCards(maxCapacity)
			coins = self.getCoins(maxCapacity)

			embed=discord.Embed(title="Click this link to join the Tournament in Clash Royale!", url="https://legendclans.com/tournaments?id={}".format(tourneydata['tag']), color=0xFAA61A)
			embed.set_thumbnail(url='https://statsroyale.com/images/tournament.png')

			embed.set_author(name=tourneydata['name']+" (#"+tourneydata['tag']+")")

			embed.add_field(name="Players", value=str(tourneydata['playerCount']) + "/" + str(maxCapacity), inline=True)
			embed.add_field(name="Status", value=tourneydata['status'].title(), inline=True)

			if tourneydata['status'] != "inProgress":
				startTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration']) - int(time.time()))
				embed.add_field(name="Starts In", value=startTime, inline=True)

			endTime = self.sec2tme((tourneydata['createTime'] + tourneydata['preparationDuration'] + tourneydata['duration']) - int(time.time()))
			embed.add_field(name="Ends In", value=endTime, inline=True)

			embed.add_field(name="Top prize", value="<:tournamentcards:380832770454192140> " + str(cards) + "	 <:coin:380832316932489268> " +  str(coins), inline=True)
			embed.set_footer(text=credits, icon_url=creditIcon)
			await self.bot.say(embed=embed)
		else:
			await self.bot.say("Found nothing, please try again after a few minutes!")
			return

def check_files():
	f = "cogs/auth.json"
	if not fileIO(f, "check"):
		print("enter your RoyaleAPI token in auth.json...")
		fileIO(f, "save", {"token" : "enter your RoyaleAPI token here!"})

def check_auth():
	c = dataIO.load_json('cogs/auth.json')
	if 'token' not in c:
		c['token'] = ""
	dataIO.save_json('cogs/auth.json', c)

def setup(bot):
	n = tournament(bot)
	check_files()
	check_auth()
	loop = asyncio.get_event_loop()
	loop.create_task(n.checkTourney())
	bot.add_cog(n)<|endoftext|>


<commit_before>""" Helpers to download a recent clang release."""

def _get_platform_folder(os_name):
    os_name = os_name.lower()
    if os_name.startswith("windows"):
        return "Win"
    if os_name.startswith("mac os"):
        return "Mac"
    if not os_name.startswith("linux"):
        fail("Unknown platform")
    return "Linux_x64"

def _download_chromium_clang(
        repo_ctx,
        platform_folder,
        package_version,
        sha256,
        out_folder):
    cds_url = "https://commondatastorage.googleapis.com/chromium-browser-clang"
    cds_file = "clang-%s.tgz" % package_version
    cds_full_url = "{0}/{1}/{2}".format(cds_url, platform_folder, cds_file)
    repo_ctx.download_and_extract(cds_full_url, output = out_folder, sha256 = sha256)

def download_clang(repo_ctx, out_folder):
    """ Download a fresh clang release and put it into out_folder.

    Clang itself will be located in 'out_folder/bin/clang'.
    We currently download one of the latest releases of clang by the
    Chromium project (see
    https://chromium.googlesource.com/chromium/src/+/master/docs/clang.md).

    Args:
      repo_ctx: An instance of repository_context object.
      out_folder: A folder to extract the compiler into.
    """
    # TODO(ibiryukov): we currently download and extract some extra tools in the
    # clang release (e.g., sanitizers). We should probably remove the ones
    # we don't need and document the ones we want provide in addition to clang.

    # Latest CLANG_REVISION and CLANG_SUB_REVISION of the Chromiums's release
    # can be found in https://chromium.googlesource.com/chromium/src/tools/clang/+/master/scripts/update.py
    CLANG_REVISION = "347933"
    CLANG_SUB_REVISION = 1

    package_version = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)

    checksums = {
        "Linux_x64": "cae3643fdf5d46fc9bc8731212bb37573547148d90b64b083165e090133d11b0",
        "Mac": "083a0e91a38c06e568652313ac7372b17a101268f7d65533d721ca30413442b4",
        "Win": "43160487cfc7e88076a369a2b6e8e4a0f42e104c28d8903f3aaa62d630aba949",
    }

    platform_folder = _get_platform_folder(repo_ctx.os.name)
    _download_chromium_clang(
        repo_ctx,
        platform_folder,
        package_version,
        checksums[platform_folder],
        out_folder,
    )
<commit_msg>Update downloadable clang to r348507<commit_after>""" Helpers to download a recent clang release."""

def _get_platform_folder(os_name):
    os_name = os_name.lower()
    if os_name.startswith("windows"):
        return "Win"
    if os_name.startswith("mac os"):
        return "Mac"
    if not os_name.startswith("linux"):
        fail("Unknown platform")
    return "Linux_x64"

def _download_chromium_clang(
        repo_ctx,
        platform_folder,
        package_version,
        sha256,
        out_folder):
    cds_url = "https://commondatastorage.googleapis.com/chromium-browser-clang"
    cds_file = "clang-%s.tgz" % package_version
    cds_full_url = "{0}/{1}/{2}".format(cds_url, platform_folder, cds_file)
    repo_ctx.download_and_extract(cds_full_url, output = out_folder, sha256 = sha256)

def download_clang(repo_ctx, out_folder):
    """ Download a fresh clang release and put it into out_folder.

    Clang itself will be located in 'out_folder/bin/clang'.
    We currently download one of the latest releases of clang by the
    Chromium project (see
    https://chromium.googlesource.com/chromium/src/+/master/docs/clang.md).

    Args:
      repo_ctx: An instance of repository_context object.
      out_folder: A folder to extract the compiler into.
    """
    # TODO(ibiryukov): we currently download and extract some extra tools in the
    # clang release (e.g., sanitizers). We should probably remove the ones
    # we don't need and document the ones we want provide in addition to clang.

    # Latest CLANG_REVISION and CLANG_SUB_REVISION of the Chromiums's release
    # can be found in https://chromium.googlesource.com/chromium/src/tools/clang/+/master/scripts/update.py
    CLANG_REVISION = "348507"
    CLANG_SUB_REVISION = 1

    package_version = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)

    checksums = {
        "Linux_x64": "85a24f215737af91e0054d3a1cb435bd8ff06178cef14241c029c8a04ff16a79",
        "Mac": "16a96a3c4b599d0418e812307087a223d5fee2ee3c7fd96f5cbc2a9e5bf8607d",
        "Win": "4c144f24d3a82d546845c680f5b029ff02dd4de7614e93d1b21cfc6e20a26dad",
    }

    platform_folder = _get_platform_folder(repo_ctx.os.name)
    _download_chromium_clang(
        repo_ctx,
        platform_folder,
        package_version,
        checksums[platform_folder],
        out_folder,
    )
<|endoftext|>


<commit_before># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2003, 2004, 2005 Edgewall Software
# Copyright (C) 2003, 2004, 2005 Jonas Borgstrm <jonas@edgewall.com>
# Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de>
#
# Trac is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Trac is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Jonas Borgstrm <jonas@edgewall.com>
#         Christopher Lenz <cmlenz@gmx.de>

from trac.attachment import Attachment
from trac.core import *
from trac.wiki.api import WikiSystem

import time

class WikiPage(object):
    """
    Represents a wiki page (new or existing).
    """
    def __init__(self, env, name=None, version=None, db=None):
        self.env = env
        self.name = name
        self._fetch(name, version, db)
        self.old_text = self.text
        self.old_readonly = self.readonly

    def _fetch(self, name, version=None, db=None):
        if not db:
            db = self.env.get_db_cnx()
        cursor = db.cursor()
        if version:
            cursor.execute("SELECT version,text,readonly FROM wiki "
                           "WHERE name=%s AND version=%s",
                           (name, int(version)))
        else:
            cursor.execute("SELECT version,text,readonly FROM wiki "
                           "WHERE name=%s ORDER BY version DESC LIMIT 1",
                           (name,))
        row = cursor.fetchone()
        if row:
            version,text,readonly = row
            self.version = int(version)
            self.text = text
            self.readonly = readonly and int(readonly) or 0
        else:
            self.version = -1
            self.text = ''
            self.readonly = 0

    exists = property(fget=lambda self: self.version >= 0)

    def delete(self, version=None, db=None):
        assert self.exists, 'Cannot delete non-existent page'
        if not db:
            db = self.env.get_db_cnx()
            handle_ta = True
        else:
            handle_ta = False

        cursor = db.cursor()
        if version is None:
            # Delete a wiki page completely
            cursor.execute("DELETE FROM wiki WHERE name=%s", (self.name,))
            self.env.log.info('Deleted page %s' % self.name)
            page_deleted = True
        else:
            # Delete only a specific page version
            cursor.execute("DELETE FROM wiki WHERE name=%s and version=%s",
                           (self.name, version))
            self.env.log.info('Deleted version %d of page %s'
                              % (version, self.name))
            cursor.execute("SELECT COUNT(*) FROM wiki WHERE name=%s",
                           (self.name,))
            if cursor.fetchone():
                page_deleted = True

        if page_deleted:
            # Delete orphaned attachments
            for attachment in Attachment.select(self.env, 'wiki', self.name, db):
                attachment.delete(db)

            # Let change listeners know about the deletion
            for listener in WikiSystem(self.env).change_listeners:
                listener.wiki_page_deleted(self)

        if handle_ta:
            db.commit()
        self.version = 0

    def save(self, author, comment, remote_addr, t=time.time(), db=None):
        if not db:
            db = self.env.get_db_cnx()
            handle_ta = True
        else:
            handle_ta = False

        if self.text != self.old_text:
            cursor = db.cursor()
            cursor.execute("INSERT INTO WIKI (name,version,time,author,ipnr,"
                           "text,comment,readonly) VALUES (%s,%s,%s,%s,%s,%s,"
                           "%s,%s)", (self.name, self.version + 1, t, author,
                           remote_addr, self.text, comment, self.readonly))
            self.version += 1
        elif self.readonly != self.old_readonly:
            cursor = db.cursor()
            cursor.execute("UPDATE wiki SET readonly=%s WHERE name=%s",
                           (self.readonly, self.name))
        else:
            raise TracError('Page not modified')

        if handle_ta:
            db.commit()

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 0:
                listener.wiki_page_added(self)
            else:
                listener.wiki_page_changed(self)

        self.old_readonly = self.readonly
        self.old_text = self.text

    def get_history(self, db=None):
        if not db:
            db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT version,time,author,comment,ipnr FROM wiki "
                       "WHERE name=%s AND version<=%s "
                       "ORDER BY version DESC", (self.name, self.version))
        for version,time,author,comment,ipnr in cursor:
            yield version,time,author,comment,ipnr
<commit_msg>Fix call to {{{IWikiChangeListener.wiki_page_changed()}}}.<commit_after># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2003, 2004, 2005 Edgewall Software
# Copyright (C) 2003, 2004, 2005 Jonas Borgstrm <jonas@edgewall.com>
# Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de>
#
# Trac is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Trac is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Jonas Borgstrm <jonas@edgewall.com>
#         Christopher Lenz <cmlenz@gmx.de>

from trac.attachment import Attachment
from trac.core import *
from trac.wiki.api import WikiSystem

import time

class WikiPage(object):
    """
    Represents a wiki page (new or existing).
    """
    def __init__(self, env, name=None, version=None, db=None):
        self.env = env
        self.name = name
        self._fetch(name, version, db)
        self.old_text = self.text
        self.old_readonly = self.readonly

    def _fetch(self, name, version=None, db=None):
        if not db:
            db = self.env.get_db_cnx()
        cursor = db.cursor()
        if version:
            cursor.execute("SELECT version,text,readonly FROM wiki "
                           "WHERE name=%s AND version=%s",
                           (name, int(version)))
        else:
            cursor.execute("SELECT version,text,readonly FROM wiki "
                           "WHERE name=%s ORDER BY version DESC LIMIT 1",
                           (name,))
        row = cursor.fetchone()
        if row:
            version,text,readonly = row
            self.version = int(version)
            self.text = text
            self.readonly = readonly and int(readonly) or 0
        else:
            self.version = -1
            self.text = ''
            self.readonly = 0

    exists = property(fget=lambda self: self.version >= 0)

    def delete(self, version=None, db=None):
        assert self.exists, 'Cannot delete non-existent page'
        if not db:
            db = self.env.get_db_cnx()
            handle_ta = True
        else:
            handle_ta = False

        cursor = db.cursor()
        if version is None:
            # Delete a wiki page completely
            cursor.execute("DELETE FROM wiki WHERE name=%s", (self.name,))
            self.env.log.info('Deleted page %s' % self.name)
            page_deleted = True
        else:
            # Delete only a specific page version
            cursor.execute("DELETE FROM wiki WHERE name=%s and version=%s",
                           (self.name, version))
            self.env.log.info('Deleted version %d of page %s'
                              % (version, self.name))
            cursor.execute("SELECT COUNT(*) FROM wiki WHERE name=%s",
                           (self.name,))
            if cursor.fetchone():
                page_deleted = True

        if page_deleted:
            # Delete orphaned attachments
            for attachment in Attachment.select(self.env, 'wiki', self.name, db):
                attachment.delete(db)

            # Let change listeners know about the deletion
            for listener in WikiSystem(self.env).change_listeners:
                listener.wiki_page_deleted(self)

        if handle_ta:
            db.commit()
        self.version = 0

    def save(self, author, comment, remote_addr, t=time.time(), db=None):
        if not db:
            db = self.env.get_db_cnx()
            handle_ta = True
        else:
            handle_ta = False

        if self.text != self.old_text:
            cursor = db.cursor()
            cursor.execute("INSERT INTO WIKI (name,version,time,author,ipnr,"
                           "text,comment,readonly) VALUES (%s,%s,%s,%s,%s,%s,"
                           "%s,%s)", (self.name, self.version + 1, t, author,
                           remote_addr, self.text, comment, self.readonly))
            self.version += 1
        elif self.readonly != self.old_readonly:
            cursor = db.cursor()
            cursor.execute("UPDATE wiki SET readonly=%s WHERE name=%s",
                           (self.readonly, self.name))
        else:
            raise TracError('Page not modified')

        if handle_ta:
            db.commit()

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 0:
                listener.wiki_page_added(self)
            else:
                listener.wiki_page_changed(self, self.version, t, author,
                                           comment, remote_addr)

        self.old_readonly = self.readonly
        self.old_text = self.text

    def get_history(self, db=None):
        if not db:
            db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT version,time,author,comment,ipnr FROM wiki "
                       "WHERE name=%s AND version<=%s "
                       "ORDER BY version DESC", (self.name, self.version))
        for version,time,author,comment,ipnr in cursor:
            yield version,time,author,comment,ipnr
<|endoftext|>