<commit_before>import json
import os
import shutil
import tempfile

import mock
from mock import patch

from jirafs import exceptions
from jirafs.utils import run_command_method_with_kwargs

from .base import BaseTestCase

class TestTicketFolder(BaseTestCase):
    def setUp(self):
        self.arbitrary_ticket_number = 'ALPHA-123'
        self.root_folder = tempfile.mkdtemp()
        self.mock_jira = mock.MagicMock()
        self.mock_jira.issue.return_value = self.rehydrate_issue(
            'basic.issue.json'
        )
        self.mock_get_jira = lambda _, config=None: self.mock_jira

        with patch(
            'jirafs.ticketfolder.TicketFolder.get_remotely_changed'
        ) as get_remotely_changed:
            get_remotely_changed.return_value = []
            self.ticketfolder = run_command_method_with_kwargs(
                'clone',
                ticket_url='http://arbitrary.com/browse/ALPHA-123',
                jira=self.mock_get_jira,
                path=os.path.join(
                    self.root_folder,
                    self.arbitrary_ticket_number,
                )
            )

    def test_cloned_issue_successfully(self):
        paths = [
            'comments.read_only.jira',
            'fields.jira',
            'description.jira',
            'new_comment.jira',
            '.jirafs/gitignore',
            '.jirafs/issue.json',
            '.jirafs/remote_files.json',
            '.jirafs/version',
        ]
        for path in paths:
            self.assertTrue(
                os.path.isfile(
                    self.ticketfolder.get_local_path(path)
                ),
                '%s does not exist' % path
            )
            # Ensure that the file is tracked in git
            try:
                self.ticketfolder.run_git_command(
                    'ls-files', path, '--error-unmatch'
                )
            except exceptions.GitCommandError:
                self.fail(
                    "File %s is not tracked in the git repository."
                )

    def test_get_fields(self):
        actual_result = self.ticketfolder.get_fields()

        expected_result = json.loads(
            self.get_asset_contents('basic.status.json')
        )

        self.assertEquals(
            actual_result,
            expected_result
        )

    def test_fetch(self):
        self.ticketfolder._issue = (
            self.rehydrate_issue('test_fetch/fetched.json')
        )
        run_command_method_with_kwargs(
            'fetch',
            folder=self.ticketfolder,
        )

        expected_result = self.get_asset_contents('test_fetch/fetched.jira')
        with open(self.ticketfolder.get_shadow_path('fields.jira')) as _in:
            actual_result = _in.read()

        self.assertEqual(actual_result, expected_result)

    def test_push(self):
        changed_field = 'description'
        changed_value = 'Something Else'

        status = self.get_empty_status()
        status['ready']['fields'][changed_field] = (
            'Something', changed_value,
        )
        with patch.object(self.ticketfolder, 'status') as status_method:
            status_method.return_value = status
            with patch.object(self.ticketfolder.issue, 'update') as out:
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder
                )
                out.assert_called_with(
                    **{
                        'description': changed_value
                    }
                )

    def test_push_rejected_if_updated(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_shadow_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        self.ticketfolder.run_git_command('add', '-A', shadow=True)
        self.ticketfolder.run_git_command(
            'commit', '-m', 'Changed', shadow=True
        )
        self.ticketfolder.run_git_command(
            'push', 'origin', 'jira', shadow=True
        )
        with self.assertRaises(exceptions.LocalCopyOutOfDate):
            run_command_method_with_kwargs(
                'push',
                folder=self.ticketfolder
            )

    def test_status_new_file(self):
        src_path = self.get_asset_path('test_status_local_changes/alpha.svg')
        dst_path = self.ticketfolder.get_local_path('alpha.svg')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['files'] = ['alpha.svg']
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def test_status_local_changes(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_local_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['fields']['assignee'] = (
            '', 'Coddington, Adam (ArbitraryCorp-Atlantis)'
        )
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def test_status_new_comment(self):
        arbitrary_comment = 'New Comment'

        comment = self.ticketfolder.get_local_path('new_comment.jira')
        with open(comment, 'w') as out:
            out.write(arbitrary_comment)

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['new_comment'] = arbitrary_comment
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def tearDown(self):
        shutil.rmtree(self.root_folder)
<commit_msg>Mock out 'pull' when testing 'push'.<commit_after>import json
import os
import shutil
import tempfile

import mock
from mock import patch

from jirafs import exceptions
from jirafs.utils import run_command_method_with_kwargs

from .base import BaseTestCase

class TestTicketFolder(BaseTestCase):
    def setUp(self):
        self.arbitrary_ticket_number = 'ALPHA-123'
        self.root_folder = tempfile.mkdtemp()
        self.mock_jira = mock.MagicMock()
        self.mock_jira.issue.return_value = self.rehydrate_issue(
            'basic.issue.json'
        )
        self.mock_get_jira = lambda _, config=None: self.mock_jira

        with patch(
            'jirafs.ticketfolder.TicketFolder.get_remotely_changed'
        ) as get_remotely_changed:
            get_remotely_changed.return_value = []
            self.ticketfolder = run_command_method_with_kwargs(
                'clone',
                ticket_url='http://arbitrary.com/browse/ALPHA-123',
                jira=self.mock_get_jira,
                path=os.path.join(
                    self.root_folder,
                    self.arbitrary_ticket_number,
                )
            )

    def test_cloned_issue_successfully(self):
        paths = [
            'comments.read_only.jira',
            'fields.jira',
            'description.jira',
            'new_comment.jira',
            '.jirafs/gitignore',
            '.jirafs/issue.json',
            '.jirafs/remote_files.json',
            '.jirafs/version',
        ]
        for path in paths:
            self.assertTrue(
                os.path.isfile(
                    self.ticketfolder.get_local_path(path)
                ),
                '%s does not exist' % path
            )
            # Ensure that the file is tracked in git
            try:
                self.ticketfolder.run_git_command(
                    'ls-files', path, '--error-unmatch'
                )
            except exceptions.GitCommandError:
                self.fail(
                    "File %s is not tracked in the git repository."
                )

    def test_get_fields(self):
        actual_result = self.ticketfolder.get_fields()

        expected_result = json.loads(
            self.get_asset_contents('basic.status.json')
        )

        self.assertEquals(
            actual_result,
            expected_result
        )

    def test_fetch(self):
        self.ticketfolder._issue = (
            self.rehydrate_issue('test_fetch/fetched.json')
        )
        run_command_method_with_kwargs(
            'fetch',
            folder=self.ticketfolder,
        )

        expected_result = self.get_asset_contents('test_fetch/fetched.jira')
        with open(self.ticketfolder.get_shadow_path('fields.jira')) as _in:
            actual_result = _in.read()

        self.assertEqual(actual_result, expected_result)

    def test_push(self):
        changed_field = 'description'
        changed_value = 'Something Else'

        status = self.get_empty_status()
        status['ready']['fields'][changed_field] = (
            'Something', changed_value,
        )
        with patch('jirafs.commands.pull.Command.pull') as pull:
            with patch.object(self.ticketfolder, 'status') as status_method:
                status_method.return_value = status
                with patch.object(self.ticketfolder.issue, 'update') as out:
                    run_command_method_with_kwargs(
                        'push',
                        folder=self.ticketfolder
                    )
                    self.assertTrue(pull.called)
                    out.assert_called_with(
                        **{
                            'description': changed_value
                        }
                    )

    def test_push_rejected_if_updated(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_shadow_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        self.ticketfolder.run_git_command('add', '-A', shadow=True)
        self.ticketfolder.run_git_command(
            'commit', '-m', 'Changed', shadow=True
        )
        self.ticketfolder.run_git_command(
            'push', 'origin', 'jira', shadow=True
        )
        with self.assertRaises(exceptions.LocalCopyOutOfDate):
            run_command_method_with_kwargs(
                'push',
                folder=self.ticketfolder
            )

    def test_status_new_file(self):
        src_path = self.get_asset_path('test_status_local_changes/alpha.svg')
        dst_path = self.ticketfolder.get_local_path('alpha.svg')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['files'] = ['alpha.svg']
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def test_status_local_changes(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_local_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['fields']['assignee'] = (
            '', 'Coddington, Adam (ArbitraryCorp-Atlantis)'
        )
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def test_status_new_comment(self):
        arbitrary_comment = 'New Comment'

        comment = self.ticketfolder.get_local_path('new_comment.jira')
        with open(comment, 'w') as out:
            out.write(arbitrary_comment)

        expected_output = self.get_empty_status()
        expected_output['uncommitted']['new_comment'] = arbitrary_comment
        actual_output = self.ticketfolder.status()

        self.assertEqual(expected_output, actual_output)

    def tearDown(self):
        shutil.rmtree(self.root_folder)
<|endoftext|>


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

import futures
import logging

from weckan import templates, urls, wsgihelpers, contexts, queries, territories

from weckan.controllers import dashboard, dataset, group, organization, redirect, reuse, resource, tags, wiki

log = logging.getLogger(__name__)
router = None

NB_DATASETS = 12

@wsgihelpers.wsgify
def home(request):
    context = contexts.Ctx(request)
    _ = context.translator.ugettext

    fake, results = dataset.search(None, request, page_size=NB_DATASETS)
    last_datasets = queries.last_datasets().limit(NB_DATASETS)

    dataset_tabs = (
        ('popular', _('Most popular'), results['results']),
        ('recent', _('Latest'), dataset.serialize(last_datasets)),
    )

    return templates.render_site('home.html', context,
        featured_reuses=queries.featured_reuses().limit(NB_DATASETS),
        territory=territories.get_cookie(request),
        dataset_tabs=dataset_tabs,
    )

@wsgihelpers.wsgify
def search_results(request):
    query = request.params.get('q', '')

    with futures.ThreadPoolExecutor(max_workers=3) as executor:
        workers = [
            executor.submit(dataset.search, query, request),
            executor.submit(organization.search, query),
            executor.submit(wiki.search, query),
        ]

    results = dict(worker.result() for worker in futures.as_completed(workers))

    return templates.render_site('search.html', request, search_query=query, has_ckan=False, **results)

@wsgihelpers.wsgify
def forbidden(request):
    return wsgihelpers.forbidden(contexts.Ctx(request))

@wsgihelpers.wsgify
def error404(request):
    return wsgihelpers.error(contexts.Ctx(request), 404)

def make_router(app):
    """Return a WSGI application that searches requests to controllers """
    global router
    controllers = group, organization, dashboard, dataset, redirect, resource, reuse, tags
    routes = (controller.routes for controller in controllers)
    routes = sum(routes, tuple())
    catchall = (
        ('GET', r'^(/(?P<lang>\w{2}))?/[\w\d_-]+/?$', error404),
    )
    routes = routes + catchall
    router = urls.make_router(app,
        ('GET', r'^(/(?P<lang>\w{2}))?/?$', home),
        ('GET', r'^(/(?P<lang>\w{2}))?/search/?$', search_results),
        ('GET', r'^(/(?P<lang>\w{2}))?/users/?$', forbidden),
        *routes
    )

    return router
<commit_msg>Added error page<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

import futures
import logging

from weckan import templates, urls, wsgihelpers, contexts, queries, territories

from weckan.controllers import dashboard, dataset, group, organization, redirect, reuse, resource, tags, wiki

log = logging.getLogger(__name__)
router = None

NB_DATASETS = 12

@wsgihelpers.wsgify
def home(request):
    context = contexts.Ctx(request)
    _ = context.translator.ugettext

    fake, results = dataset.search(None, request, page_size=NB_DATASETS)
    last_datasets = queries.last_datasets().limit(NB_DATASETS)

    dataset_tabs = (
        ('popular', _('Most popular'), results['results']),
        ('recent', _('Latest'), dataset.serialize(last_datasets)),
    )

    return templates.render_site('home.html', context,
        featured_reuses=queries.featured_reuses().limit(NB_DATASETS),
        territory=territories.get_cookie(request),
        dataset_tabs=dataset_tabs,
    )

@wsgihelpers.wsgify
def search_results(request):
    query = request.params.get('q', '')

    with futures.ThreadPoolExecutor(max_workers=3) as executor:
        workers = [
            executor.submit(dataset.search, query, request),
            executor.submit(organization.search, query),
            executor.submit(wiki.search, query),
        ]

    results = dict(worker.result() for worker in futures.as_completed(workers))

    return templates.render_site('search.html', request, search_query=query, has_ckan=False, **results)

@wsgihelpers.wsgify
def forbidden(request):
    return wsgihelpers.forbidden(contexts.Ctx(request))

@wsgihelpers.wsgify
def error404(request):
    return wsgihelpers.error(contexts.Ctx(request), 404)

@wsgihelpers.wsgify
def error(request):
    context = contexts.Ctx(request)
    code = int(request.urlvars.get('code', 500) or 500)
    return wsgihelpers.error(context, code)

def make_router(app):
    """Return a WSGI application that searches requests to controllers """
    global router
    controllers = group, organization, dashboard, dataset, redirect, resource, reuse, tags
    routes = (controller.routes for controller in controllers)
    routes = sum(routes, tuple())
    catchall = (
        ('GET', r'^(/(?P<lang>\w{2}))?/[\w\d_-]+/?$', error404),
    )
    routes = routes + catchall
    router = urls.make_router(app,
        ('GET', r'^(/(?P<lang>\w{2}))?/?$', home),
        ('GET', r'^(/(?P<lang>\w{2}))?/error(/(?P<code>\d{3}))?/?$', error),
        ('GET', r'^(/(?P<lang>\w{2}))?/search/?$', search_results),
        ('GET', r'^(/(?P<lang>\w{2}))?/users/?$', forbidden),
        *routes
    )

    return router
<|endoftext|>


<commit_before>import json
from mfcloud.attach import attach_to_container
import os
from flexmock import flexmock
from mfcloud import txhttp
from mfcloud.container import DockerfileImageBuilder
from mfcloud.test_utils import real_docker
from mfcloud.txdocker import DockerTwistedClient
import pytest
import re
from twisted.internet import defer

@pytest.fixture
def client():
    with real_docker():
        client = DockerTwistedClient()
        return client

@pytest.inlineCallbacks
def test_images(client):

    result = yield client.images(name='image_that_do_not_exist_ever_326782387')
    assert result == []

@pytest.inlineCallbacks
def test_images_that_exist(client):

    result = yield client.images(name='ubuntu')
    assert 'ubuntu:latest' in result[0]['RepoTags']

@pytest.inlineCallbacks
def test_images_all(client):

    result = yield client.images()

    assert len(result) > 1

@pytest.inlineCallbacks
@pytest.mark.xfail
def test_build(client):

    class Publisher(object):

        def __init__(self):
            self.called = 0

        def publish(self, data, tag):
            assert tag == 'log-123123'
            assert len(data) > 0

            self.called += 1

    client.message_publisher = Publisher()

    builder = DockerfileImageBuilder(os.path.join(os.path.dirname(__file__), '_files/ct_bash'))

    d = builder.create_archive()

    def build_image(docker_file):
        return client.build_image(docker_file, ticket_id=123123)

    d.addCallback(build_image)

    result = yield d

    assert re.match('^[0-9a-f]+$', result)

    assert client.message_publisher.called > 0
<commit_msg>Fix tests<commit_after>import json
from mfcloud.attach import attach_to_container
import os
from flexmock import flexmock
from mfcloud import txhttp
from mfcloud.container import DockerfileImageBuilder
from mfcloud.test_utils import real_docker
from mfcloud.txdocker import DockerTwistedClient
import pytest
import re
from twisted.internet import defer

@pytest.fixture
def client():
    with real_docker():
        client = DockerTwistedClient()
        return client

@pytest.inlineCallbacks
def test_images(client):

    result = yield client.images(name='image_that_do_not_exist_ever_326782387')
    assert result == []

@pytest.inlineCallbacks
def test_images_that_exist(client):

    result = yield client.images(name='ubuntu')
    assert result[0]['RepoTags'][0].startswith('ubuntu:')

@pytest.inlineCallbacks
def test_images_all(client):

    result = yield client.images()

    assert len(result) > 1

@pytest.inlineCallbacks
@pytest.mark.xfail
def test_build(client):

    class Publisher(object):

        def __init__(self):
            self.called = 0

        def publish(self, data, tag):
            assert tag == 'log-123123'
            assert len(data) > 0

            self.called += 1

    client.message_publisher = Publisher()

    builder = DockerfileImageBuilder(os.path.join(os.path.dirname(__file__), '_files/ct_bash'))

    d = builder.create_archive()

    def build_image(docker_file):
        return client.build_image(docker_file, ticket_id=123123)

    d.addCallback(build_image)

    result = yield d

    assert re.match('^[0-9a-f]+$', result)

    assert client.message_publisher.called > 0
<|endoftext|>


<commit_before>class MergeDict(object):
    """
    A simple class for creating new "virtual" dictionaries that actualy look
    up values in more than one dictionary, passed in the constructor.
    """
    def __init__(self, *dicts):
        self.dicts = dicts

    def __getitem__(self, key):
        for dict_ in self.dicts:
            try:
                return dict_[key]
            except KeyError:
                pass
        raise KeyError

    def __copy__(self):
        return self.__class__(*self.dicts)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

    def getlist(self, key):
        for dict_ in self.dicts:
            try:
                return dict_.getlist(key)
            except KeyError:
                pass
        raise KeyError

    def items(self):
        item_list = []
        for dict_ in self.dicts:
            item_list.extend(dict_.items())
        return item_list

    def has_key(self, key):
        for dict_ in self.dicts:
            if key in dict_:
                return True
        return False

    __contains__ = has_key

    def copy(self):
        """Returns a copy of this object."""
        return self.__copy__()

class SortedDict(dict):
    """
    A dictionary that keeps its keys in the order in which they're inserted.
    """
    def __init__(self, data=None):
        if data is None:
            data = {}
        super(SortedDict, self).__init__(data)
        if isinstance(data, dict):
            self.keyOrder = data.keys()
        else:
            self.keyOrder = [key for key, value in data]

    def __deepcopy__(self, memo):
        from copy import deepcopy
        return self.__class__([(key, deepcopy(value, memo))
                               for key, value in self.iteritems()])

    def __setitem__(self, key, value):
        super(SortedDict, self).__setitem__(key, value)
        if key not in self.keyOrder:
            self.keyOrder.append(key)

    def __delitem__(self, key):
        super(SortedDict, self).__delitem__(key)
        self.keyOrder.remove(key)

    def __iter__(self):
        for k in self.keyOrder:
            yield k

    def pop(self, k, *args):
        result = super(SortedDict, self).pop(k, *args)
        try:
            self.keyOrder.remove(k)
        except ValueError:
            # Key wasn't in the dictionary in the first place. No problem.
            pass
        return result

    def popitem(self):
        result = super(SortedDict, self).popitem()
        self.keyOrder.remove(result[0])
        return result

    def items(self):
        return zip(self.keyOrder, self.values())

    def iteritems(self):
        for key in self.keyOrder:
            yield key, super(SortedDict, self).__getitem__(key)

    def keys(self):
        return self.keyOrder[:]

    def iterkeys(self):
        return iter(self.keyOrder)

    def values(self):
        return [super(SortedDict, self).__getitem__(k) for k in self.keyOrder]

    def itervalues(self):
        for key in self.keyOrder:
            yield super(SortedDict, self).__getitem__(key)

    def update(self, dict_):
        for k, v in dict_.items():
            self.__setitem__(k, v)

    def setdefault(self, key, default):
        if key not in self.keyOrder:
            self.keyOrder.append(key)
        return super(SortedDict, self).setdefault(key, default)

    def value_for_index(self, index):
        """Returns the value of the item at the given zero-based index."""
        return self[self.keyOrder[index]]

    def insert(self, index, key, value):
        """Inserts the key, value pair before the item with the given index."""
        if key in self.keyOrder:
            n = self.keyOrder.index(key)
            del self.keyOrder[n]
            if n < index:
                index -= 1
        self.keyOrder.insert(index, key)
        super(SortedDict, self).__setitem__(key, value)

    def copy(self):
        """Returns a copy of this object."""
        # This way of initializing the copy means it works for subclasses, too.
        obj = self.__class__(self)
        obj.keyOrder = self.keyOrder
        return obj

    def __repr__(self):
        """
        Replaces the normal dict.__repr__ with a version that returns the keys
        in their sorted order.
        """
        return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])

class MultiValueDictKeyError(KeyError):
    pass

class MultiValueDict(dict):
    """
    A subclass of dictionary customized to handle multiple values for the
    same key.

    >>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
    >>> d['name']
    'Simon'
    >>> d.getlist('name')
    ['Adrian', 'Simon']
    >>> d.get('lastname', 'nonexistent')
    'nonexistent'
    >>> d.setlist('lastname', ['Holovaty', 'Willison'])

    This class exists to solve the irritating problem raised by cgi.parse_qs,
    which returns a list for every key, even though most Web forms submit
    single name-value pairs.
    """
    def __init__(self, key_to_list_mapping=()):
        super(MultiValueDict, self).__init__(key_to_list_mapping)

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__,
                             super(MultiValueDict, self).__repr__())

    def __getitem__(self, key):
        """
        Returns the last data value for this key, or [] if it's an empty list;
        raises KeyError if not found.
        """
        try:
            list_ = super(MultiValueDict, self).__getitem__(key)
        except KeyError:
            raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self)
        try:
            return list_[-1]
        except IndexError:
            return []

    def __setitem__(self, key, value):
        super(MultiValueDict, self).__setitem__(key, [value])

    def __copy__(self):
        return self.__class__(super(MultiValueDict, self).items())

    def __deepcopy__(self, memo=None):
        import copy
        if memo is None:
            memo = {}
        result = self.__class__()
        memo[id(self)] = result
        for key, value in dict.items(self):
            dict.__setitem__(result, copy.deepcopy(key, memo),
                             copy.deepcopy(value, memo))
        return result

    def get(self, key, default=None):
        """Returns the default value if the requested data doesn't exist."""
        try:
            val = self[key]
        except KeyError:
            return default
        if val == []:
            return default
        return val

    def getlist(self, key):
        """Returns an empty list if the requested data doesn't exist."""
        try:
            return super(MultiValueDict, self).__getitem__(key)
        except KeyError:
            return []

    def setlist(self, key, list_):
        super(MultiValueDict, self).__setitem__(key, list_)

    def setdefault(self, key, default=None):
        if key not in self:
            self[key] = default
        return self[key]

    def setlistdefault(self, key, default_list=()):
        if key not in self:
            self.setlist(key, default_list)
        return self.getlist(key)

    def appendlist(self, key, value):
        """Appends an item to the internal list associated with key."""
        self.setlistdefault(key, [])
        super(MultiValueDict, self).__setitem__(key, self.getlist(key) + [value])

    def items(self):
        """
        Returns a list of (key, value) pairs, where value is the last item in
        the list associated with the key.
        """
        return [(key, self[key]) for key in self.keys()]

    def lists(self):
        """Returns a list of (key, list) pairs."""
        return super(MultiValueDict, self).items()

    def values(self):
        """Returns a list of the last value on every key list."""
        return [self[key] for key in self.keys()]

    def copy(self):
        """Returns a copy of this object."""
        return self.__deepcopy__()

    def update(self, *args, **kwargs):
        """
        update() extends rather than replaces existing key lists.
        Also accepts keyword args.
        """
        if len(args) > 1:
            raise TypeError, "update expected at most 1 arguments, got %d" % len(args)
        if args:
            other_dict = args[0]
            if isinstance(other_dict, MultiValueDict):
                for key, value_list in other_dict.lists():
                    self.setlistdefault(key, []).extend(value_list)
            else:
                try:
                    for key, value in other_dict.items():
                        self.setlistdefault(key, []).append(value)
                except TypeError:
                    raise ValueError, "MultiValueDict.update() takes either a MultiValueDict or dictionary"
        for key, value in kwargs.iteritems():
            self.setlistdefault(key, []).append(value)

class DotExpandedDict(dict):
    """
    A special dictionary constructor that takes a dictionary in which the keys
    may contain dots to specify inner dictionaries. It's confusing, but this
    example should make sense.

    >>> d = DotExpandedDict({'person.1.firstname': ['Simon'], \
            'person.1.lastname': ['Willison'], \
            'person.2.firstname': ['Adrian'], \
            'person.2.lastname': ['Holovaty']})
    >>> d
    {'person': {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}}
    >>> d['person']
    {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}
    >>> d['person']['1']
    {'lastname': ['Willison'], 'firstname': ['Simon']}

    # Gotcha: Results are unpredictable if the dots are "uneven":
    >>> DotExpandedDict({'c.1': 2, 'c.2': 3, 'c': 1})
    {'c': 1}
    """
    def __init__(self, key_to_list_mapping):
        for k, v in key_to_list_mapping.items():
            current = self
            bits = k.split('.')
            for bit in bits[:-1]:
                current = current.setdefault(bit, {})
            # Now assign value to current position
            try:
                current[bits[-1]] = v
            except TypeError: # Special-case if current isn't a dict.
                current = {bits[-1]: v}

class FileDict(dict):
    """
    A dictionary used to hold uploaded file contents. The only special feature
    here is that repr() of this object won't dump the entire contents of the
    file to the output. A handy safeguard for a large file upload.
    """
    def __repr__(self):
        if 'content' in self:
            d = dict(self, content='<omitted>')
            return dict.__repr__(d)
        return dict.__repr__(self)
<commit_msg>Made `MultiValueDict`'s `get` and `getlist` method docstrings more descriptive.<commit_after>class MergeDict(object):
    """
    A simple class for creating new "virtual" dictionaries that actualy look
    up values in more than one dictionary, passed in the constructor.
    """
    def __init__(self, *dicts):
        self.dicts = dicts

    def __getitem__(self, key):
        for dict_ in self.dicts:
            try:
                return dict_[key]
            except KeyError:
                pass
        raise KeyError

    def __copy__(self):
        return self.__class__(*self.dicts)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

    def getlist(self, key):
        for dict_ in self.dicts:
            try:
                return dict_.getlist(key)
            except KeyError:
                pass
        raise KeyError

    def items(self):
        item_list = []
        for dict_ in self.dicts:
            item_list.extend(dict_.items())
        return item_list

    def has_key(self, key):
        for dict_ in self.dicts:
            if key in dict_:
                return True
        return False

    __contains__ = has_key

    def copy(self):
        """Returns a copy of this object."""
        return self.__copy__()

class SortedDict(dict):
    """
    A dictionary that keeps its keys in the order in which they're inserted.
    """
    def __init__(self, data=None):
        if data is None:
            data = {}
        super(SortedDict, self).__init__(data)
        if isinstance(data, dict):
            self.keyOrder = data.keys()
        else:
            self.keyOrder = [key for key, value in data]

    def __deepcopy__(self, memo):
        from copy import deepcopy
        return self.__class__([(key, deepcopy(value, memo))
                               for key, value in self.iteritems()])

    def __setitem__(self, key, value):
        super(SortedDict, self).__setitem__(key, value)
        if key not in self.keyOrder:
            self.keyOrder.append(key)

    def __delitem__(self, key):
        super(SortedDict, self).__delitem__(key)
        self.keyOrder.remove(key)

    def __iter__(self):
        for k in self.keyOrder:
            yield k

    def pop(self, k, *args):
        result = super(SortedDict, self).pop(k, *args)
        try:
            self.keyOrder.remove(k)
        except ValueError:
            # Key wasn't in the dictionary in the first place. No problem.
            pass
        return result

    def popitem(self):
        result = super(SortedDict, self).popitem()
        self.keyOrder.remove(result[0])
        return result

    def items(self):
        return zip(self.keyOrder, self.values())

    def iteritems(self):
        for key in self.keyOrder:
            yield key, super(SortedDict, self).__getitem__(key)

    def keys(self):
        return self.keyOrder[:]

    def iterkeys(self):
        return iter(self.keyOrder)

    def values(self):
        return [super(SortedDict, self).__getitem__(k) for k in self.keyOrder]

    def itervalues(self):
        for key in self.keyOrder:
            yield super(SortedDict, self).__getitem__(key)

    def update(self, dict_):
        for k, v in dict_.items():
            self.__setitem__(k, v)

    def setdefault(self, key, default):
        if key not in self.keyOrder:
            self.keyOrder.append(key)
        return super(SortedDict, self).setdefault(key, default)

    def value_for_index(self, index):
        """Returns the value of the item at the given zero-based index."""
        return self[self.keyOrder[index]]

    def insert(self, index, key, value):
        """Inserts the key, value pair before the item with the given index."""
        if key in self.keyOrder:
            n = self.keyOrder.index(key)
            del self.keyOrder[n]
            if n < index:
                index -= 1
        self.keyOrder.insert(index, key)
        super(SortedDict, self).__setitem__(key, value)

    def copy(self):
        """Returns a copy of this object."""
        # This way of initializing the copy means it works for subclasses, too.
        obj = self.__class__(self)
        obj.keyOrder = self.keyOrder
        return obj

    def __repr__(self):
        """
        Replaces the normal dict.__repr__ with a version that returns the keys
        in their sorted order.
        """
        return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])

class MultiValueDictKeyError(KeyError):
    pass

class MultiValueDict(dict):
    """
    A subclass of dictionary customized to handle multiple values for the
    same key.

    >>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
    >>> d['name']
    'Simon'
    >>> d.getlist('name')
    ['Adrian', 'Simon']
    >>> d.get('lastname', 'nonexistent')
    'nonexistent'
    >>> d.setlist('lastname', ['Holovaty', 'Willison'])

    This class exists to solve the irritating problem raised by cgi.parse_qs,
    which returns a list for every key, even though most Web forms submit
    single name-value pairs.
    """
    def __init__(self, key_to_list_mapping=()):
        super(MultiValueDict, self).__init__(key_to_list_mapping)

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__,
                             super(MultiValueDict, self).__repr__())

    def __getitem__(self, key):
        """
        Returns the last data value for this key, or [] if it's an empty list;
        raises KeyError if not found.
        """
        try:
            list_ = super(MultiValueDict, self).__getitem__(key)
        except KeyError:
            raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self)
        try:
            return list_[-1]
        except IndexError:
            return []

    def __setitem__(self, key, value):
        super(MultiValueDict, self).__setitem__(key, [value])

    def __copy__(self):
        return self.__class__(super(MultiValueDict, self).items())

    def __deepcopy__(self, memo=None):
        import copy
        if memo is None:
            memo = {}
        result = self.__class__()
        memo[id(self)] = result
        for key, value in dict.items(self):
            dict.__setitem__(result, copy.deepcopy(key, memo),
                             copy.deepcopy(value, memo))
        return result

    def get(self, key, default=None):
        """
        Returns the last data value for the passed key.  If key doesn't exist
        or value is an empty list, then default is returned.
        """
        try:
            val = self[key]
        except KeyError:
            return default
        if val == []:
            return default
        return val

    def getlist(self, key):
        """
        Returns the list of values for the passed key.  If key doesn't exist,
        then an empty list is returned.
        """
        try:
            return super(MultiValueDict, self).__getitem__(key)
        except KeyError:
            return []

    def setlist(self, key, list_):
        super(MultiValueDict, self).__setitem__(key, list_)

    def setdefault(self, key, default=None):
        if key not in self:
            self[key] = default
        return self[key]

    def setlistdefault(self, key, default_list=()):
        if key not in self:
            self.setlist(key, default_list)
        return self.getlist(key)

    def appendlist(self, key, value):
        """Appends an item to the internal list associated with key."""
        self.setlistdefault(key, [])
        super(MultiValueDict, self).__setitem__(key, self.getlist(key) + [value])

    def items(self):
        """
        Returns a list of (key, value) pairs, where value is the last item in
        the list associated with the key.
        """
        return [(key, self[key]) for key in self.keys()]

    def lists(self):
        """Returns a list of (key, list) pairs."""
        return super(MultiValueDict, self).items()

    def values(self):
        """Returns a list of the last value on every key list."""
        return [self[key] for key in self.keys()]

    def copy(self):
        """Returns a copy of this object."""
        return self.__deepcopy__()

    def update(self, *args, **kwargs):
        """
        update() extends rather than replaces existing key lists.
        Also accepts keyword args.
        """
        if len(args) > 1:
            raise TypeError, "update expected at most 1 arguments, got %d" % len(args)
        if args:
            other_dict = args[0]
            if isinstance(other_dict, MultiValueDict):
                for key, value_list in other_dict.lists():
                    self.setlistdefault(key, []).extend(value_list)
            else:
                try:
                    for key, value in other_dict.items():
                        self.setlistdefault(key, []).append(value)
                except TypeError:
                    raise ValueError, "MultiValueDict.update() takes either a MultiValueDict or dictionary"
        for key, value in kwargs.iteritems():
            self.setlistdefault(key, []).append(value)

class DotExpandedDict(dict):
    """
    A special dictionary constructor that takes a dictionary in which the keys
    may contain dots to specify inner dictionaries. It's confusing, but this
    example should make sense.

    >>> d = DotExpandedDict({'person.1.firstname': ['Simon'], \
            'person.1.lastname': ['Willison'], \
            'person.2.firstname': ['Adrian'], \
            'person.2.lastname': ['Holovaty']})
    >>> d
    {'person': {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}}
    >>> d['person']
    {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}
    >>> d['person']['1']
    {'lastname': ['Willison'], 'firstname': ['Simon']}

    # Gotcha: Results are unpredictable if the dots are "uneven":
    >>> DotExpandedDict({'c.1': 2, 'c.2': 3, 'c': 1})
    {'c': 1}
    """
    def __init__(self, key_to_list_mapping):
        for k, v in key_to_list_mapping.items():
            current = self
            bits = k.split('.')
            for bit in bits[:-1]:
                current = current.setdefault(bit, {})
            # Now assign value to current position
            try:
                current[bits[-1]] = v
            except TypeError: # Special-case if current isn't a dict.
                current = {bits[-1]: v}

class FileDict(dict):
    """
    A dictionary used to hold uploaded file contents. The only special feature
    here is that repr() of this object won't dump the entire contents of the
    file to the output. A handy safeguard for a large file upload.
    """
    def __repr__(self):
        if 'content' in self:
            d = dict(self, content='<omitted>')
            return dict.__repr__(d)
        return dict.__repr__(self)
<|endoftext|>


<commit_before>import pytest
from mock import MagicMock

from user_sync.engine.umapi import UmapiTargetInfo, UmapiConnectors, RuleProcessor

@pytest.fixture
def rule_processor():
    return RuleProcessor({})

@pytest.fixture()
def mock_umapi_connectors():
    def _mock_umapi_connectors(*args):
        return UmapiConnectors(
            MockUmapiConnector(),
            {a: MockUmapiConnector(name=a) for a in args})

    return _mock_umapi_connectors

@pytest.fixture()
def mock_umapi_info():
    def _mock_umapi_info(name=None, groups=[]):
        mock_umapi_info = UmapiTargetInfo(name)
        for g in groups:
            mock_umapi_info.add_mapped_group(g)
        return mock_umapi_info

    return _mock_umapi_info

class MockUmapiConnector(MagicMock):
    class MockActionManager:
        def get_statistics(self):
            return 10, 2

    def __init__(self, name='', options={}, *args, **kwargs):
        super(MockUmapiConnector, self).__init__(*args, **kwargs)
        self.name = 'umapi' + name
        self.trusted = False
        self.options = options
        self.action_manager = MockUmapiConnector.MockActionManager()
        self.commands_sent = None
        self.users = {}

    def send_commands(self, commands):
        self.commands_sent = commands

    def get_action_manager(self):
        return self.action_manager

    def iter_users(self):
        return self.users<commit_msg>umapi_engine_tests <commit_after>import pytest
from mock import MagicMock

from user_sync.engine.umapi import UmapiTargetInfo, UmapiConnectors, RuleProcessor
from user_sync.connector.connector_umapi import Commands

@pytest.fixture
def rule_processor():
    return RuleProcessor({})

@pytest.fixture()
def mock_umapi_connectors():
    def _mock_umapi_connectors(*args):
        return UmapiConnectors(
            MockUmapiConnector(),
            {a: MockUmapiConnector(name=a) for a in args})

    return _mock_umapi_connectors

@pytest.fixture()
def mock_umapi_info():
    def _mock_umapi_info(name=None, groups=[]):
        mock_umapi_info = UmapiTargetInfo(name)
        for g in groups:
            mock_umapi_info.add_mapped_group(g)
        return mock_umapi_info

    return _mock_umapi_info

class MockUmapiConnector(MagicMock):
    class MockActionManager:
        def get_statistics(self):
            return 10, 2

    def __init__(self, name='', options={}, *args, **kwargs):
        super(MockUmapiConnector, self).__init__(*args, **kwargs)
        self.name = 'umapi' + name
        self.trusted = False
        self.options = options
        self.action_manager = MockUmapiConnector.MockActionManager()
        self.commands_sent = None
        self.users = {}

    def send_commands(self, commands):
        self.commands_sent = commands

    def get_action_manager(self):
        return self.action_manager

    def iter_users(self):
        return self.users

    def test_create_umapi_user(self, rule_processor, mock_dir_user, mock_umapi_info):
        user = mock_dir_user
        rp = rule_processor

        key = rp.get_user_key(user['identity_type'], user['username'], user['domain'])
        rp.directory_user_by_user_key[key] = user
        rp.options['process_groups'] = True
        rp.push_umapi = True

        groups_to_add = {'Group A', 'Group C'}
        info = mock_umapi_info(None, {'Group A', 'Group B'})
        conn = MockUmapiConnector()
        rp.create_umapi_user(key, groups_to_add, info, conn)

        result = vars(conn.commands_sent)['do_list']
        result[0][1].pop('on_conflict')
        assert result[0] == ('create', {
            'email': user['email'],
            'first_name': user['firstname'],
            'last_name': user['lastname'],
            'country': user['country']})
        assert result[1] == ('remove_from_groups', {
            'groups': {'group b', 'group a'}})
        assert result[2] == ('add_to_groups', {
            'groups': {'Group C', 'Group A'}})

    def test_update_umapi_user(self, rule_processor, mock_dir_user, mock_umapi_user, get_mock_user_list):
        rp = rule_processor
        user = mock_dir_user
        mock_umapi_user['email'] = user['email']
        mock_umapi_user['username'] = user['username']
        mock_umapi_user['domain'] = user['domain']
        mock_umapi_user['type'] = user['identity_type']

        def update(up_user, up_attrs):
            group_add = set()
            group_rem = set()
            conn = MockUmapiConnector()
            info = UmapiTargetInfo(None)
            user_key = rp.get_user_key(up_user['identity_type'], up_user['username'], up_user['domain'])
            rp.directory_user_by_user_key[user_key] = up_user
            rp.update_umapi_user(info, user_key, conn, up_attrs, group_add, group_rem, mock_umapi_user)
            assert user_key in rp.updated_user_keys
            return vars(conn.commands_sent)

        up_attrs = {
            'firstname': user['firstname'],
            'lastname': user['lastname']}

        result = update(user, up_attrs)
        assert result == {
            'identity_type': user['identity_type'],
            'email': user['email'],
            'username': user['username'],
            'domain': user['domain'],
            'do_list': [('update', {
                'first_name': user['firstname'],
                'last_name': user['lastname']})]}

        user['username'] = 'different@example.com'
        result = update(user, up_attrs)
        assert result['username'] == user['email']

        user['email'] = 'different@example.com'
        up_attrs = {
            'email': user['email']}
        result = update(user, up_attrs)

        assert result == {
            'identity_type': user['identity_type'],
            'email': user['email'],
            'username': user['username'],
            'domain': user['domain'],
            'do_list': [('update', {
                'email': 'different@example.com',
                'username': user['username']})]}

    def test_create_umapi_commands_for_directory_user(self, rule_processor, mock_dir_user):
        rp = rule_processor
        user = mock_dir_user

        def get_commands(user, update_option='ignoreIfAlreadyExists'):
            attributes = rp.get_user_attributes(user)
            attributes['country'] = user['country']
            attributes['option'] = update_option
            commands = Commands(user['identity_type'], user['email'], user['username'], user['domain'])
            commands.add_user(attributes)
            return commands

        # simple case
        commands = get_commands(user)
        result = rp.create_umapi_commands_for_directory_user(user)
        assert vars(result) == vars(commands)

        # test do_update
        commands = get_commands(user, 'updateIfAlreadyExists')
        result = rp.create_umapi_commands_for_directory_user(user, do_update=True)
        assert vars(result) == vars(commands)

        # test username format
        user['username'] = 'nosymbol'
        commands = get_commands(user)
        result = rp.create_umapi_commands_for_directory_user(user)
        assert vars(result) == vars(commands)

        # test username format
        user['username'] = 'different@example.com'
        commands = get_commands(user)
        commands.update_user({
            "email": user['email'],
            "username": user['username']})
        commands.username = user['email']
        result = rp.create_umapi_commands_for_directory_user(user)
        assert vars(result) == vars(commands)

        # test console trusted
        user['username'] = 'different@example.com'
        commands = get_commands(user)
        commands.username = user['email']
        result = rp.create_umapi_commands_for_directory_user(user, console_trusted=True)
        assert vars(result) == vars(commands)

        # Default Country Code as None and Id Type as federatedID. Country as None in user
        rp.options['default_country_code'] = None
        user['country'] = None
        result = rp.create_umapi_commands_for_directory_user(user)
        assert result is None

        # Default Country Code as None with Id Type as enterpriseID. Country as None in user
        rp.options['default_country_code'] = None
        user['identity_type'] = 'enterpriseID'
        result = rp.create_umapi_commands_for_directory_user(user)
        user['country'] = 'UD'
        commands = get_commands(user)
        assert vars(result) == vars(commands)

        # Having Default Country Code with value 'US'. Country as None in user.
        rp.options['default_country_code'] = 'US'
        user['country'] = None
        result = rp.create_umapi_commands_for_directory_user(user)
        user['country'] = 'US'
        commands = get_commands(user)
        assert vars(result) == vars(commands)

        # Country as 'CA' in user
        user['country'] = 'CA'
        result = rp.create_umapi_commands_for_directory_user(user)
        commands = get_commands(user)
        assert vars(result) == vars(commands)

    def test_get_user_attribute_difference(self, rule_processor, mock_dir_user, mock_umapi_user):
        directory_user_mock_data = mock_dir_user
        umapi_users_mock_data = mock_umapi_user
        umapi_users_mock_data['firstname'] = 'Adobe'
        umapi_users_mock_data['lastname'] = 'Username'
        umapi_users_mock_data['email'] = 'adobe.username@example.com'

        expected = {
            'email': mock_dir_user['email'],
            'firstname': mock_dir_user['firstname'],
            'lastname': mock_dir_user['lastname']
        }

        assert expected == rule_processor.get_user_attribute_difference(
            directory_user_mock_data, umapi_users_mock_data)

        # test with no change
        assert rule_processor.get_user_attribute_difference(
            umapi_users_mock_data, umapi_users_mock_data) == {}<|endoftext|>


<commit_before>import xbmc
import xbmcgui
import requests
from xbmctorrent import plugin, torrent2http
from xbmctorrent.ga import track_event

class TorrentPlayer(xbmc.Player):
    # def __init__(self, *args, **kwargs):
    #     super(TorrentPlayer).__init__(self, *args, **kwargs)

    def init(self, magnet_uri):
        track_event("torrent_player", "start")
        self.magnet_uri = magnet_uri
        self.torrent2http = torrent2http.start(magnet=magnet_uri)
        track_event("download", "start", magnet_uri)
        xbmc.sleep(1000)
        self.dialog = xbmcgui.DialogProgress()
        self.dialog_hidden = True
        self.status = {}
        self.is_playing = False
        self.is_paused = False
        self.is_stopped = False
        return self

    def get_title(self):
        return xbmc.getInfoLabel("Player.Title")

    def show_dialog(self):
        if self.dialog_hidden:
            self.dialog_hidden = False
            self.dialog.create(plugin.name)

    def hide_dialog(self):
        if not self.dialog_hidden:
            self.dialog_hidden = True
            self.dialog.close()

    def onPlayBackStarted(self):
        self.is_playing = True
        self.is_paused = False
        self.is_stopped = False
        self.hide_dialog()
        plugin.log.info(self.get_title())
        track_event("video", "play", self.get_title())

    def onPlayBackResumed(self):
        self.onPlayBackStarted()

    def onPlayBackPaused(self):
        self.is_playing = False
        self.is_paused = True
        self.is_stopped = False
        track_event("video", "pause", self.get_title())

    def onPlayBackStopped(self):
        self.is_playing = False
        self.is_paused = False
        self.is_stopped = True
        track_event("video", "stop", self.get_title())

    def loop(self):
        state_str = ['Queued', 'Checking', 'Downloading metadata', \
                     'Downloading', 'Finished', 'Seeding', 'Allocating', "Allocating file & Checking resume"]

        has_resolved = False
        self.show_dialog()
        last_status = None
        while True:
            if xbmc.abortRequested or self.is_stopped:
                self.torrent2http.shutdown()
                return

            if self.dialog.iscanceled():
                self.hide_dialog()
                self.torrent2http.shutdown()
                return

            status = requests.get("http://%s/status" % self.torrent2http.get_bind_address()).json()
            if status["state"] != last_status:
                track_event("torrent_player", state_str[status["state"]], self.magnet_uri)
                last_status = status["state"]
            if not self.dialog_hidden:
                if status["state"] >= 0:
                    self.dialog.update(
                        int(status["progress"] * 100),
                        state_str[status["state"]],
                        "%.2f%% D:%.2fkb/s U:%.2fkb/s" % (status["progress"] * 100, status["download_rate"], status["upload_rate"]),
                        "S:%d P:%d" % (status["num_seeds"], status["num_peers"])
                    )

            if self.is_paused:
                plugin.notify(
                    "%.2f%% D:%.2fkb/s U:%.2fkb/s" % (status["progress"] * 100, status["download_rate"], status["upload_rate"]),
                    "XBMCtorrent - %s" % state_str[status["state"]],
                    delay=1000)

            if status["total_pieces"] > 0 and not has_resolved:
                percentage = float(status["max_piece"]) / float(status["total_pieces"]) * 100.0
                if percentage >= 0.5: # we can start playback at 0.5%
                    has_resolved = True
                    plugin.set_resolved_url({
                        "path": "http://%s/file" % self.torrent2http.get_bind_address(),
                        "is_playable": True,
                    })
            xbmc.sleep(1000)

        track_event("torrent_player", "shutdown")
<commit_msg>Torrent Info dialog now appears when paused (doesn't work on Aeon Nox btw)<commit_after>import xbmc
import xbmcgui
import requests
from xbmctorrent import plugin, torrent2http
from xbmctorrent.ga import track_event

class TorrentPlayer(xbmc.Player):
    # def __init__(self, *args, **kwargs):
    #     super(TorrentPlayer).__init__(self, *args, **kwargs)

    def init(self, magnet_uri):
        track_event("torrent_player", "start")
        self.magnet_uri = magnet_uri
        self.torrent2http = torrent2http.start(magnet=magnet_uri)
        track_event("download", "start", magnet_uri)
        xbmc.sleep(1000)
        self.dialog = xbmcgui.DialogProgress()
        self.dialog_hidden = True
        self.status = {}
        self.is_playing = False
        self.is_paused = False
        self.is_stopped = False
        return self

    def get_title(self):
        return xbmc.getInfoLabel("Player.Title")

    def show_dialog(self):
        if self.dialog_hidden:
            self.dialog_hidden = False
            self.dialog.create(plugin.name)

    def hide_dialog(self):
        if not self.dialog_hidden:
            self.dialog_hidden = True
            self.dialog.close()

    def onPlayBackStarted(self):
        self.is_playing = True
        self.is_paused = False
        self.is_stopped = False
        self.hide_dialog()
        plugin.log.info(self.get_title())
        track_event("video", "play", self.get_title())

    def onPlayBackResumed(self):
        self.onPlayBackStarted()

    def onPlayBackPaused(self):
        self.is_playing = False
        self.is_paused = True
        self.is_stopped = False
        track_event("video", "pause", self.get_title())

    def onPlayBackStopped(self):
        self.is_playing = False
        self.is_paused = False
        self.is_stopped = True
        track_event("video", "stop", self.get_title())

    def loop(self):
        state_str = ['Queued', 'Checking', 'Downloading metadata', \
                     'Downloading', 'Finished', 'Seeding', 'Allocating', "Allocating file & Checking resume"]

        has_resolved = False
        self.show_dialog()
        last_status = None
        while not (xbmc.abortRequested or self.dialog.iscanceled() or self.is_stopped):
            status = requests.get("http://%s/status" % self.torrent2http.get_bind_address()).json()
            if status["state"] != last_status:
                track_event("torrent_player", state_str[status["state"]], self.magnet_uri)
                last_status = status["state"]

            if self.is_paused:
                self.show_dialog()

            if not self.dialog_hidden:
                if status["state"] >= 0:
                    self.dialog.update(
                        int(status["progress"] * 100),
                        state_str[status["state"]],
                        "%.2f%% D:%.2fkb/s U:%.2fkb/s" % (status["progress"] * 100, status["download_rate"], status["upload_rate"]),
                        "S:%d P:%d" % (status["num_seeds"], status["num_peers"])
                    )

            if status["total_pieces"] > 0 and not has_resolved:
                percentage = float(status["max_piece"]) / float(status["total_pieces"]) * 100.0
                if percentage >= 0.5: # we can start playback at 0.5%
                    has_resolved = True
                    plugin.set_resolved_url({
                        "path": "http://%s/file" % self.torrent2http.get_bind_address(),
                        "is_playable": True,
                    })
            xbmc.sleep(500)

        self.hide_dialog()
        self.torrent2http.shutdown()
        track_event("torrent_player", "shutdown")
<|endoftext|>


<commit_before>import os
from time import sleep

import pytest
import redis

from django_q.brokers import get_broker, Broker
from django_q.conf import Conf
from django_q.humanhash import uuid

def test_broker():
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.lock_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    # stats
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'
    # stats with no cache
    Conf.CACHE = 'not_configured'
    broker.cache = broker.get_cache()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') is None
    assert broker.get_stats('test:*') is None
    Conf.CACHE = 'default'

def test_redis():
    Conf.DJANGO_REDIS = None
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    Conf.REDIS = {'host': '127.0.0.1', 'port': 7799}
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()
    Conf.REDIS = None
    Conf.DJANGO_REDIS = 'default'

def test_custom():
    Conf.BROKER = 'brokers.redis_broker.Redis'
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.__class__.__name == 'Redis'
    Conf.BROKER = None

def test_disque():
    Conf.DISQUE_NODES = ['127.0.0.1:7711']
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    Conf.DISQUE_FASTACK = True
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    Conf.DISQUE_NODES = ['127.0.0.1:7798', '127.0.0.1:7799']
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()
    # back to django-redis
    Conf.DISQUE_NODES = None
    Conf.DISQUE_FASTACK = False

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq():
    Conf.DISQUE_NODES = None
    Conf.SQS = None
    Conf.IRON_MQ = {'token': os.getenv('IRON_MQ_TOKEN'),
                    'project_id': os.getenv('IRON_MQ_PROJECT_ID')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    # Conf.RETRY = 1
    # broker.enqueue('test')
    # assert broker.dequeue() is not None
    # sleep(3)
    # assert broker.dequeue() is not None
    # task = broker.dequeue()[0]
    # assert len(task) > 0
    # broker.acknowledge(task[0])
    # sleep(3)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()
    # back to django-redis
    Conf.IRON_MQ = None
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs():
    Conf.IRON_MQ = None
    Conf.DISQUE_NODES = None
    Conf.SQS = {'aws_region': os.getenv('AWS_REGION'),
                'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(2)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(2)
    # delete job
    broker.enqueue('test')
    task_id = broker.dequeue()[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    Conf.BULK = 12
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    assert broker.lock_size() == 0
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    # back to django-redis
    Conf.SQS = None
    Conf.BULK = 1
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.django_db
def test_orm():
    Conf.ORM = 'default'
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    assert broker.lock_size() == Conf.BULK
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None

@pytest.mark.django_db
def test_mongo():
    Conf.MONGO = {'host': '127.0.0.1', 'port': 27017}
    # check broker
    broker = get_broker(list_key='mongo_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    tasks = []
    for i in range(5):
        tasks.append(broker.dequeue()[0])
    assert broker.lock_size() == 5
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None
<commit_msg>Fixes typo<commit_after>import os
from time import sleep

import pytest
import redis

from django_q.brokers import get_broker, Broker
from django_q.conf import Conf
from django_q.humanhash import uuid

def test_broker():
    broker = Broker()
    broker.enqueue('test')
    broker.dequeue()
    broker.queue_size()
    broker.lock_size()
    broker.purge_queue()
    broker.delete('id')
    broker.delete_queue()
    broker.acknowledge('test')
    broker.ping()
    broker.info()
    # stats
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') == 'test'
    assert broker.get_stats('test:*')[0] == 'test'
    # stats with no cache
    Conf.CACHE = 'not_configured'
    broker.cache = broker.get_cache()
    assert broker.get_stat('test_1') is None
    broker.set_stat('test_1', 'test', 3)
    assert broker.get_stat('test_1') is None
    assert broker.get_stats('test:*') is None
    Conf.CACHE = 'default'

def test_redis():
    Conf.DJANGO_REDIS = None
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    Conf.REDIS = {'host': '127.0.0.1', 'port': 7799}
    broker = get_broker()
    with pytest.raises(Exception):
        broker.ping()
    Conf.REDIS = None
    Conf.DJANGO_REDIS = 'default'

def test_custom():
    Conf.BROKER = 'brokers.redis_broker.Redis'
    broker = get_broker()
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.__class__.__name__ == 'Redis'
    Conf.BROKER = None

def test_disque():
    Conf.DISQUE_NODES = ['127.0.0.1:7711']
    # check broker
    broker = get_broker(list_key='disque_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    Conf.DISQUE_FASTACK = True
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # connection test
    Conf.DISQUE_NODES = ['127.0.0.1:7798', '127.0.0.1:7799']
    with pytest.raises(redis.exceptions.ConnectionError):
        broker.get_connection()
    # back to django-redis
    Conf.DISQUE_NODES = None
    Conf.DISQUE_FASTACK = False

@pytest.mark.skipif(not os.getenv('IRON_MQ_TOKEN'),
                    reason="requires IronMQ credentials")
def test_ironmq():
    Conf.DISQUE_NODES = None
    Conf.SQS = None
    Conf.IRON_MQ = {'token': os.getenv('IRON_MQ_TOKEN'),
                    'project_id': os.getenv('IRON_MQ_PROJECT_ID')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    # initialize the queue
    broker.enqueue('test')
    # clear before we start
    broker.purge_queue()
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    # Conf.RETRY = 1
    # broker.enqueue('test')
    # assert broker.dequeue() is not None
    # sleep(3)
    # assert broker.dequeue() is not None
    # task = broker.dequeue()[0]
    # assert len(task) > 0
    # broker.acknowledge(task[0])
    # sleep(3)
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    assert broker.dequeue() is None
    broker.delete_queue()
    # back to django-redis
    Conf.IRON_MQ = None
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.skipif(not os.getenv('AWS_ACCESS_KEY_ID'),
                    reason="requires AWS credentials")
def test_sqs():
    Conf.IRON_MQ = None
    Conf.DISQUE_NODES = None
    Conf.SQS = {'aws_region': os.getenv('AWS_REGION'),
                'aws_access_key_id': os.getenv('AWS_ACCESS_KEY_ID'),
                'aws_secret_access_key': os.getenv('AWS_SECRET_ACCESS_KEY')}
    # check broker
    broker = get_broker(list_key=uuid()[0])
    assert broker.ping() is True
    assert broker.info() is not None
    assert broker.queue_size() == 0
    # enqueue
    broker.enqueue('test')
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.dequeue() is None
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.dequeue() is not None
    sleep(2)
    task = broker.dequeue()[0]
    assert len(task) > 0
    broker.acknowledge(task[0])
    sleep(2)
    # delete job
    broker.enqueue('test')
    task_id = broker.dequeue()[0][0]
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    broker.enqueue('test')
    while task is None:
        task = broker.dequeue()[0]
    broker.fail(task[0])
    # bulk test
    for i in range(10):
        broker.enqueue('test')
    Conf.BULK = 12
    tasks = broker.dequeue()
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # duplicate acknowledge
    broker.acknowledge(task[0])
    assert broker.lock_size() == 0
    # delete queue
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    # back to django-redis
    Conf.SQS = None
    Conf.BULK = 1
    Conf.DJANGO_REDIS = 'default'

@pytest.mark.django_db
def test_orm():
    Conf.ORM = 'default'
    # check broker
    broker = get_broker(list_key='orm_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    Conf.BULK = 5
    tasks = broker.dequeue()
    assert broker.lock_size() == Conf.BULK
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None

@pytest.mark.django_db
def test_mongo():
    Conf.MONGO = {'host': '127.0.0.1', 'port': 27017}
    # check broker
    broker = get_broker(list_key='mongo_test')
    assert broker.ping() is True
    assert broker.info() is not None
    # clear before we start
    broker.delete_queue()
    # enqueue
    broker.enqueue('test')
    assert broker.queue_size() == 1
    # dequeue
    task = broker.dequeue()[0]
    assert task[1] == 'test'
    broker.acknowledge(task[0])
    assert broker.queue_size() == 0
    # Retry test
    Conf.RETRY = 1
    broker.enqueue('test')
    assert broker.queue_size() == 1
    broker.dequeue()
    assert broker.queue_size() == 0
    sleep(1.5)
    assert broker.queue_size() == 1
    task = broker.dequeue()[0]
    assert broker.queue_size() == 0
    broker.acknowledge(task[0])
    sleep(1.5)
    assert broker.queue_size() == 0
    # delete job
    task_id = broker.enqueue('test')
    broker.delete(task_id)
    assert broker.dequeue() is None
    # fail
    task_id = broker.enqueue('test')
    broker.fail(task_id)
    # bulk test
    for i in range(5):
        broker.enqueue('test')
    tasks = []
    for i in range(5):
        tasks.append(broker.dequeue()[0])
    assert broker.lock_size() == 5
    for task in tasks:
        assert task is not None
        broker.acknowledge(task[0])
    # test lock size
    assert broker.lock_size() == 0
    # test duplicate acknowledge
    broker.acknowledge(task[0])
    # delete queue
    broker.enqueue('test')
    broker.enqueue('test')
    broker.purge_queue()
    broker.delete_queue()
    assert broker.queue_size() == 0
    # back to django-redis
    Conf.ORM = None
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import unittest
import os
import swc2vtk

class TestVtkGenerator(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        pass

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.swc_file_path = os.path.join('tests', 'simple.swc')
        self.data_file_path = os.path.join('tests', 'simple.dat')
        self.output_file_path = os.path.join('output.vtk')
        self.vtk_generator = swc2vtk.VtkGenerator()

    def tearDown(self):
        self.vtk_generator.write_vtk(self.output_file_path)

    def test_add_cylinder(self):
        self.vtk_generator.add_cylinder()

    def test_add_sphere(self):
        self.vtk_generator.add_sphere()

    def test_add_swc(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_add_swc_flip(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path, inv_x=True, inv_y=True, inv_z=True,
                                   shift_x=100, shift_y=100, shift_z=100)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_add_datafile(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path)
        self.vtk_generator.add_datafile(self.data_file_path)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_draw_mode1(self):
        self.vtk_generator.set_draw_mode(1)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode2(self):
        self.vtk_generator.set_draw_mode(2)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode3(self):
        self.vtk_generator.set_draw_mode(3)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode4(self):
        self.vtk_generator.set_draw_mode(4)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_write_vtk_options(self):
        self.vtk_generator.add_swc(self.swc_file_path)
        self.vtk_generator.write_vtk(self.output_file_path, fixval=True, movingval=True, coloring=True,
                                     diam_ratio=0.2, normalize_diam=True, radius_data=True)

def suite():
    suite = unittest.TestSuite()
    suite.addTests(unittest.makeSuite(TestVtkGenerator))
    return suite

if __name__ == '__main__':
    unittest.main()
<commit_msg>add test for volume rendering<commit_after># -*- coding: utf-8 -*-
import unittest
import os
import swc2vtk

class TestVtkGenerator(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        pass

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.swc_file_path = os.path.join('tests', 'simple.swc')
        self.data_file_path = os.path.join('tests', 'simple.dat')
        self.output_file_path = os.path.join('output.vtk')
        self.vtk_generator = swc2vtk.VtkGenerator()

    def tearDown(self):
        self.vtk_generator.write_vtk(self.output_file_path)

    def test_add_cylinder(self):
        self.vtk_generator.add_cylinder()

    def test_add_sphere(self):
        self.vtk_generator.add_sphere()

    def test_add_swc(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_add_swc_flip(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path, inv_x=True, inv_y=True, inv_z=True,
                                   shift_x=100, shift_y=100, shift_z=100)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_add_datafile(self):
        simple_cmp_size = 11
        self.vtk_generator.add_swc(self.swc_file_path)
        self.vtk_generator.add_datafile(self.data_file_path)
        self.assertEqual(simple_cmp_size, len(self.vtk_generator.swc_list[0].data))

    def test_draw_mode1(self):
        self.vtk_generator.set_draw_mode(1)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode2(self):
        self.vtk_generator.set_draw_mode(2)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode3(self):
        self.vtk_generator.set_draw_mode(3)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_draw_mode4(self):
        self.vtk_generator.set_draw_mode(4)
        self.vtk_generator.add_swc(self.swc_file_path)

    def test_write_vtk_options(self):
        self.vtk_generator.add_swc(self.swc_file_path)
        self.vtk_generator.write_vtk(self.output_file_path, fixval=True, movingval=True, coloring=True,
                                     diam_ratio=0.2, normalize_diam=True, radius_data=True)

    def test_write_volume_vtk(self):
        self.vtk_generator.add_swc(self.swc_file_path)
        self.vtk_generator.write_volume_vtk(self.output_file_path, origin=(-100, -100, -100), ratio=(4.0, 4.0, 4.0))

def suite():
    suite = unittest.TestSuite()
    suite.addTests(unittest.makeSuite(TestVtkGenerator))
    return suite

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>from contextlib import contextmanager
from datetime import datetime
import hashlib
import time
import json
import os

from django.core import serializers
from django.conf import settings
from django.db import models

if not hasattr(settings, 'SERIALIZATION_MODULES'):
    settings.SERIALIZATION_MODULES = {}
if 'django_snailtracker.serializer' not in settings.SERIALIZATION_MODULES:
    settings.SERIALIZATION_MODULES['django_snailtracker.serializer'] = 'django_snailtracker.serializer'

SNAILTRACKER_TMP_PATH = getattr(settings, 'SNAILTRACKER_TMP_PATH', '/tmp/')
SNAILTRACKER_TIMEOUT_SECONDS = getattr(settings, 'SNAILTRACKER_TIMEOUT_SECONDS', 5)

def snailtracker_enabled():
    return getattr(settings, 'SNAILTRACKER_ENABLED', False)

def make_model_snapshot(instance):
    object_as_dict = json.loads(
            serializers.serialize(
                'django_snailtracker.serializer', [instance]))[0]
    if hasattr(instance, 'snailtracker_exclude_fields'):
        for field in instance.snailtracker_exclude_fields:
            try:
                del object_as_dict['fields'][field]
            except KeyError:
                pass
    return object_as_dict

def dict_diff(d1, d2):
    c_list = list()
    for k, v in d1.iteritems():
        if unicode(d2[k]) != unicode(v):
            c_list.append(k)
    return c_list

def dict_diff_with_values(dict1, dict2):
    the_diff = {}
    for k, v in dict1.iteritems():
        if unicode(dict2[k]) != unicode(v):
            the_diff[k] = {'old': dict1[k], 'new': dict2[k]}
    return the_diff

def diff_from_action(action, values=True):
    if action.post_init_snapshot and action.post_save_snapshot:
        if not values:
            return dict_diff(
                action.init_snapshot_to_python()['fields'],
                action.save_snapshot_to_python()['fields'])
        else:
            return dict_diff_with_values(
                action.init_snapshot_to_python()['fields'],
                action.save_snapshot_to_python()['fields'])

class SnailtrackerMutexLockedError(Exception):
    pass

class OverDueLock(Exception):
    pass

@contextmanager
def mutex_lock(model_instance):
    ObjectLock = models.get_model('django_snailtracker', 'ObjectLock')
    table = model_instance._meta.db_table
    pk = model_instance.pk
    mutex_key = hashlib.md5(
        '{table}{pk}'.format(table=table, pk=pk)).hexdigest()
    try:
        lock = ObjectLock.objects.get(pk=mutex_key)
        created_at_delta = datetime.now() - lock.created_at
        over_due = created_at_delta.seconds > SNAILTRACKER_TIMEOUT_SECONDS
        if not over_due:
            raise SnailtrackerMutexLockedError(
                "{table}:{pk} is already locked".format(table=table, pk=pk))
        else:
            lock.delete()
            raise OverDueLock
    except (ObjectLock.DoesNotExist, OverDueLock):
        lock = ObjectLock.objects.create(
            pk=mutex_key, table=table, object_pk=pk)
    try:
        yield True
    finally:
        lock.delete()
        if os.path.exists(mutex_key):
            os.remove(mutex_key)
<commit_msg>stray filesystem code from merge<commit_after>from contextlib import contextmanager
from datetime import datetime
import hashlib
import time
import json
import os

from django.core import serializers
from django.conf import settings
from django.db import models

if not hasattr(settings, 'SERIALIZATION_MODULES'):
    settings.SERIALIZATION_MODULES = {}
if 'django_snailtracker.serializer' not in settings.SERIALIZATION_MODULES:
    settings.SERIALIZATION_MODULES['django_snailtracker.serializer'] = 'django_snailtracker.serializer'

SNAILTRACKER_TMP_PATH = getattr(settings, 'SNAILTRACKER_TMP_PATH', '/tmp/')
SNAILTRACKER_TIMEOUT_SECONDS = getattr(settings, 'SNAILTRACKER_TIMEOUT_SECONDS', 5)

def snailtracker_enabled():
    return getattr(settings, 'SNAILTRACKER_ENABLED', False)

def make_model_snapshot(instance):
    object_as_dict = json.loads(
            serializers.serialize(
                'django_snailtracker.serializer', [instance]))[0]
    if hasattr(instance, 'snailtracker_exclude_fields'):
        for field in instance.snailtracker_exclude_fields:
            try:
                del object_as_dict['fields'][field]
            except KeyError:
                pass
    return object_as_dict

def dict_diff(d1, d2):
    c_list = list()
    for k, v in d1.iteritems():
        if unicode(d2[k]) != unicode(v):
            c_list.append(k)
    return c_list

def dict_diff_with_values(dict1, dict2):
    the_diff = {}
    for k, v in dict1.iteritems():
        if unicode(dict2[k]) != unicode(v):
            the_diff[k] = {'old': dict1[k], 'new': dict2[k]}
    return the_diff

def diff_from_action(action, values=True):
    if action.post_init_snapshot and action.post_save_snapshot:
        if not values:
            return dict_diff(
                action.init_snapshot_to_python()['fields'],
                action.save_snapshot_to_python()['fields'])
        else:
            return dict_diff_with_values(
                action.init_snapshot_to_python()['fields'],
                action.save_snapshot_to_python()['fields'])

class SnailtrackerMutexLockedError(Exception):
    pass

class OverDueLock(Exception):
    pass

@contextmanager
def mutex_lock(model_instance):
    ObjectLock = models.get_model('django_snailtracker', 'ObjectLock')
    table = model_instance._meta.db_table
    pk = model_instance.pk
    mutex_key = hashlib.md5(
        '{table}{pk}'.format(table=table, pk=pk)).hexdigest()
    try:
        lock = ObjectLock.objects.get(pk=mutex_key)
        created_at_delta = datetime.now() - lock.created_at
        over_due = created_at_delta.seconds > SNAILTRACKER_TIMEOUT_SECONDS
        if not over_due:
            raise SnailtrackerMutexLockedError(
                "{table}:{pk} is already locked".format(table=table, pk=pk))
        else:
            lock.delete()
            raise OverDueLock
    except (ObjectLock.DoesNotExist, OverDueLock):
        lock = ObjectLock.objects.create(
            pk=mutex_key, table=table, object_pk=pk)
    try:
        yield True
    finally:
        lock.delete()
<|endoftext|>


<commit_before>import stp

from rj_gameplay.tactic import wall_tactic, nmark_tactic, goalie_tactic
import stp.role
from stp.role.assignment.naive import NaiveRoleAssignment
import stp.rc
from typing import Dict, List, Tuple, Type
from rj_gameplay.calculations import wall_calculations

import stp.role.cost
from rj_msgs.msg import RobotIntent

class BasicDefense(stp.play.Play):
    """For when we don't have the ball and are trying to stop the opponent from scoring."""

    def __init__(self):
        super().__init__()

        # super simple FSM
        # TODO: use FSM class (or at least don't use string literals)
        self.state = "init"

    def tick(
        self,
        world_state: stp.rc.WorldState,
    ) -> List[RobotIntent]:

        if self.state is "init":
            # TODO: had to add this check or role assignment behaved oddly
            #       fix by updating gameplay node to only tick once world_state is not None
            # if world_state is not None:
            if True:
                self.prioritized_tactics.append(
                    goalie_tactic.GoalieTactic(world_state, 0)
                )
                self.prioritized_tactics.append(wall_tactic.WallTactic(world_state, 5))
                # TODO: add nmark tactic
                #       and make it go for the ball (rather than stopping in front)
                self.assign_roles(world_state)
                self.state = "active"
                return self.get_robot_intents(world_state)
        elif self.state is "active":
            # return robot intents from assigned tactics back to gameplay node
            return self.get_robot_intents(world_state)
<commit_msg>do what last commit said; did not make correct edit<commit_after>import stp

from rj_gameplay.tactic import wall_tactic, nmark_tactic, goalie_tactic
import stp.role
from stp.role.assignment.naive import NaiveRoleAssignment
import stp.rc
from typing import Dict, List, Tuple, Type
from rj_gameplay.calculations import wall_calculations

import stp.role.cost
from rj_msgs.msg import RobotIntent

class BasicDefense(stp.play.Play):
    """For when we don't have the ball and are trying to stop the opponent from scoring."""

    def __init__(self):
        super().__init__()

        # super simple FSM
        # TODO: use FSM class (or at least don't use string literals)
        self.state = "init"

    def tick(
        self,
        world_state: stp.rc.WorldState,
    ) -> List[RobotIntent]:

        if self.state is "init":
            self.prioritized_tactics.append(
                goalie_tactic.GoalieTactic(world_state, 0)
            )
            self.prioritized_tactics.append(wall_tactic.WallTactic(world_state, 5))
            # TODO: add nmark tactic
            #       and make it go for the ball (rather than stopping in front)
            self.assign_roles(world_state)
            self.state = "active"
            return self.get_robot_intents(world_state)
        elif self.state is "active":
            # return robot intents from assigned tactics back to gameplay node
            return self.get_robot_intents(world_state)
<|endoftext|>