<commit_before>import json
import time
from http import HTTPStatus
from threading import Thread
from typing import Union, List, Optional
from unittest import TestCase
from uuid import uuid4

import requests
from requests.auth import HTTPBasicAuth

from openbrokerapi import api, errors
from openbrokerapi.catalog import ServicePlan
from openbrokerapi.service_broker import ServiceBroker, Service, ProvisionDetails, ProvisionedServiceSpec, \
    ProvisionState, LastOperation, OperationState, DeprovisionDetails, DeprovisionServiceSpec, BindDetails, Binding, \
    BindState, UnbindDetails, UnbindSpec

class FullBrokerTestCase(TestCase):

    def setUp(self) -> None:
        broker_username = str(uuid4())
        broker_passsword = str(uuid4())
        self.request_ads = {
            'auth': HTTPBasicAuth(broker_username, broker_passsword),
            'headers': {'X-Broker-Api-Version': '2.15', 'Content-Type': 'application/json'}
        }

        self.service_guid = str(uuid4())
        self.plan_guid = str(uuid4())
        self.broker = InMemoryBroker(self.service_guid, self.plan_guid)

        def run_server():
            api.serve(self.broker, api.BrokerCredentials(broker_username, broker_passsword))

        # self.server = Process(target=run_server)
        self.server = Thread(target=run_server)
        self.server.setDaemon(True)
        self.server.start()
        time.sleep(2)

    def test_lifecycle(self):
        # GIVEN
        org_guid = str(uuid4())
        space_guid = str(uuid4())
        instace_guid = str(uuid4())
        binding_guid = str(uuid4())

        # CATALOG
        self.check_catalog(self.service_guid, self.plan_guid)

        # ASYNC PROVISION
        operation = self.check_provision(instace_guid, org_guid, space_guid, self.service_guid, self.plan_guid)
        self.check_last_operation_after_provision(instace_guid, operation)

        # GET INSTANCE
        # todo missing endpoints

        # ASYNC BIND
        operation = self.check_bind(binding_guid, instace_guid)
        self.check_last_operation_after_bind(binding_guid, instace_guid, operation)

        # GET BINDING
        # todo missing endpoints

        # ASYNC UNBIND
        operation = self.check_unbind(binding_guid, instace_guid)
        self.check_last_operation_after_unbind(binding_guid, instace_guid, operation)

        # ASYNC DEPROVISION
        operation = self.check_deprovision(instace_guid, operation)
        self.check_last_operation_after_deprovision(instace_guid, operation)

        # DEPROVISION TWICE
        self.check_deprovision_after_deprovision_done(instace_guid)

    def check_unbind(self, binding_guid, instace_guid):
        response = requests.delete(
            "http://localhost:5000/v2/service_instances/{}/service_bindings/{}".format(instace_guid, binding_guid),
            params={
                "service_id": self.service_guid,
                "plan_id": self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads
        )
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json().get('operation')
        self.assertEqual('unbind', operation)
        return operation

    def check_last_operation_after_bind(self, binding_guid, instace_guid, operation):
        response = requests.get(
            'http://localhost:5000/v2/service_instances/{}/service_bindings/{}/last_operation'.format(instace_guid,
                                                                                binding_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation,
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_last_operation_after_unbind(self, binding_guid, instace_guid, operation):
        response = requests.get(
            'http://localhost:5000/v2/service_instances/{}/service_bindings/{}/last_operation'.format(instace_guid,
                                                                                binding_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation,
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_bind(self, binding_guid, instace_guid):
        response = requests.put(
            "http://localhost:5000/v2/service_instances/{}/service_bindings/{}?accepts_incomplete=true".format(
                instace_guid, binding_guid),
            data=json.dumps({
                "service_id": self.service_guid,
                "plan_id": self.plan_guid
            }),
            **self.request_ads
        )
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json().get('operation')
        self.assertEqual('bind', operation)
        return operation

    def check_deprovision_after_deprovision_done(self, instace_guid):
        response = requests.delete(
            "http://localhost:5000/v2/service_instances/{}".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.GONE, response.status_code)

    def check_deprovision(self, instace_guid, operation):
        response = requests.delete(
            "http://localhost:5000/v2/service_instances/{}".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json()['operation']
        self.assertEqual('deprovision', operation)
        return operation

    def check_last_operation_after_deprovision(self, instace_guid, operation):
        response = requests.get(
            "http://localhost:5000/v2/service_instances/{}/last_operation".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.GONE, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_last_operation_after_provision(self, instace_guid, operation):
        response = requests.get(
            "http://localhost:5000/v2/service_instances/{}/last_operation".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_provision(self, instace_guid, org_guid, space_guid, service_guid, plan_guid):
        response = requests.put(
            "http://localhost:5000/v2/service_instances/{}?accepts_incomplete=true".format(instace_guid),
            data=json.dumps({
                "organization_guid": org_guid,
                "space_guid": space_guid,
                "service_id": service_guid,
                "plan_id": plan_guid,
                # "context": {
                #     "organization_guid": "org-guid-here",
                #     "space_guid": "space-guid-here",
                # }
            }),
            **self.request_ads)
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)

        operation = response.json().get('operation')
        self.assertEqual('provision', operation)

        return operation

    def check_catalog(self, service_guid, plan_guid):
        response = requests.get('http://localhost:5000/v2/catalog', **self.request_ads)
        catalog = response.json()
        self.assertEqual(HTTPStatus.OK, response.status_code)
        # find service
        for service in catalog['services']:
            if service['name'] == 'InMemService':
                break
        else:
            service = None
        self.assertIsNotNone(service)
        self.assertEqual(service_guid, service.get('id'))

        # find plan
        for plan in service['plans']:
            if plan['name'] == 'standard':
                break
        else:
            plan = None
        self.assertIsNotNone(plan)
        self.assertEqual(plan_guid, plan.get('id'))

class InMemoryBroker(ServiceBroker):
    CREATING = 'CREATING'
    CREATED = 'CREATED'
    BINDING = 'BINDING'
    BOUND = 'BOUND'
    UNBINDING = 'UNBINDING'
    DELETING = 'DELETING'

    def __init__(self, service_guid, plan_guid):
        self.service_guid = service_guid
        self.plan_guid = plan_guid

        self.service_instances = dict()

    def catalog(self) -> Union[Service, List[Service]]:
        return Service(
            id=self.service_guid,
            name='InMemService',
            description='InMemService',
            bindable=True,
            plans=[
                ServicePlan(
                    id=self.plan_guid,
                    name='standard',
                    description='standard plan',
                    free=False,
                )
            ]
        )

    def provision(self,
                  instance_id: str,
                  details: ProvisionDetails,
                  async_allowed: bool,
                  **kwargs) -> ProvisionedServiceSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        self.service_instances[instance_id] = {
            'provision_details': details,
            'state': self.CREATING
        }

        return ProvisionedServiceSpec(
            state=ProvisionState.IS_ASYNC,
            operation='provision'
        )

    def bind(self, instance_id: str, binding_id: str, details: BindDetails, async_allowed: bool, **kwargs) -> Binding:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id, {})
        if instance and instance.get('state') == self.CREATED:
            instance['state'] = self.BINDING
            return Binding(BindState.IS_ASYNC, operation='bind')

    def unbind(self, instance_id: str, binding_id: str, details: UnbindDetails, async_allowed: bool,
               **kwargs) -> UnbindSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id, {})
        if instance and instance.get('state') == self.BOUND:
            instance['state'] = self.UNBINDING
            return UnbindSpec(True, 'unbind')

    def deprovision(self, instance_id: str, details: DeprovisionDetails, async_allowed: bool,
                    **kwargs) -> DeprovisionServiceSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id)
        if instance is None:
            raise errors.ErrInstanceDoesNotExist()

        if instance.get('state') == self.CREATED:
            instance['state'] = self.DELETING
            return DeprovisionServiceSpec(True, 'deprovision')

    def last_operation(self, instance_id: str, operation_data: Optional[str], **kwargs) -> LastOperation:
        instance = self.service_instances.get(instance_id)
        if instance is None:
            raise errors.ErrInstanceDoesNotExist()

        if instance.get('state') == self.CREATING:
            instance['state'] = self.CREATED
            return LastOperation(OperationState.SUCCEEDED)
        elif instance.get('state') == self.DELETING:
            del self.service_instances[instance_id]
            raise errors.ErrInstanceDoesNotExist()

    def last_binding_operation(self,
                               instance_id: str,
                               binding_id: str,
                               operation_data: Optional[str],
                               **kwargs
                               ) -> LastOperation:
        instance = self.service_instances.get(instance_id, {})
        if instance.get('state') == self.BINDING:
            instance['state'] = self.BOUND
            return LastOperation(OperationState.SUCCEEDED)
        elif instance.get('state') == self.UNBINDING:
            instance['state'] = self.CREATED
            return LastOperation(OperationState.SUCCEEDED)
<commit_msg>Fix issue with used port in integration test<commit_after>import json
import time
from http import HTTPStatus
from threading import Thread
from typing import Union, List, Optional
from unittest import TestCase
from uuid import uuid4

import requests
from requests.auth import HTTPBasicAuth

from openbrokerapi import api, errors
from openbrokerapi.catalog import ServicePlan
from openbrokerapi.service_broker import ServiceBroker, Service, ProvisionDetails, ProvisionedServiceSpec, \
    ProvisionState, LastOperation, OperationState, DeprovisionDetails, DeprovisionServiceSpec, BindDetails, Binding, \
    BindState, UnbindDetails, UnbindSpec

class FullBrokerTestCase(TestCase):

    def setUp(self) -> None:
        broker_username = str(uuid4())
        broker_passsword = str(uuid4())
        self.request_ads = {
            'auth': HTTPBasicAuth(broker_username, broker_passsword),
            'headers': {'X-Broker-Api-Version': '2.15', 'Content-Type': 'application/json'}
        }

        self.service_guid = str(uuid4())
        self.plan_guid = str(uuid4())
        self.broker = InMemoryBroker(self.service_guid, self.plan_guid)

        def run_server():
            api.serve(self.broker, api.BrokerCredentials(broker_username, broker_passsword), port=5001)

        # self.server = Process(target=run_server)
        self.server = Thread(target=run_server)
        self.server.setDaemon(True)
        self.server.start()
        time.sleep(2)

    def test_lifecycle(self):
        # GIVEN
        org_guid = str(uuid4())
        space_guid = str(uuid4())
        instace_guid = str(uuid4())
        binding_guid = str(uuid4())

        # CATALOG
        self.check_catalog(self.service_guid, self.plan_guid)

        # ASYNC PROVISION
        operation = self.check_provision(instace_guid, org_guid, space_guid, self.service_guid, self.plan_guid)
        self.check_last_operation_after_provision(instace_guid, operation)

        # GET INSTANCE
        # todo missing endpoints

        # ASYNC BIND
        operation = self.check_bind(binding_guid, instace_guid)
        self.check_last_operation_after_bind(binding_guid, instace_guid, operation)

        # GET BINDING
        # todo missing endpoints

        # ASYNC UNBIND
        operation = self.check_unbind(binding_guid, instace_guid)
        self.check_last_operation_after_unbind(binding_guid, instace_guid, operation)

        # ASYNC DEPROVISION
        operation = self.check_deprovision(instace_guid, operation)
        self.check_last_operation_after_deprovision(instace_guid, operation)

        # DEPROVISION TWICE
        self.check_deprovision_after_deprovision_done(instace_guid)

    def check_unbind(self, binding_guid, instace_guid):
        response = requests.delete(
            "http://localhost:5001/v2/service_instances/{}/service_bindings/{}".format(instace_guid, binding_guid),
            params={
                "service_id": self.service_guid,
                "plan_id": self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads
        )
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json().get('operation')
        self.assertEqual('unbind', operation)
        return operation

    def check_last_operation_after_bind(self, binding_guid, instace_guid, operation):
        response = requests.get(
            'http://localhost:5001/v2/service_instances/{}/service_bindings/{}/last_operation'.format(instace_guid,
                                                                                binding_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation,
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_last_operation_after_unbind(self, binding_guid, instace_guid, operation):
        response = requests.get(
            'http://localhost:5001/v2/service_instances/{}/service_bindings/{}/last_operation'.format(instace_guid,
                                                                                binding_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation,
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_bind(self, binding_guid, instace_guid):
        response = requests.put(
            "http://localhost:5001/v2/service_instances/{}/service_bindings/{}?accepts_incomplete=true".format(
                instace_guid, binding_guid),
            data=json.dumps({
                "service_id": self.service_guid,
                "plan_id": self.plan_guid
            }),
            **self.request_ads
        )
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json().get('operation')
        self.assertEqual('bind', operation)
        return operation

    def check_deprovision_after_deprovision_done(self, instace_guid):
        response = requests.delete(
            "http://localhost:5001/v2/service_instances/{}".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.GONE, response.status_code)

    def check_deprovision(self, instace_guid, operation):
        response = requests.delete(
            "http://localhost:5001/v2/service_instances/{}".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'accepts_incomplete': 'true'
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)
        operation = response.json()['operation']
        self.assertEqual('deprovision', operation)
        return operation

    def check_last_operation_after_deprovision(self, instace_guid, operation):
        response = requests.get(
            "http://localhost:5001/v2/service_instances/{}/last_operation".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.GONE, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_last_operation_after_provision(self, instace_guid, operation):
        response = requests.get(
            "http://localhost:5001/v2/service_instances/{}/last_operation".format(instace_guid),
            params={
                'service_id': self.service_guid,
                'plan_id': self.plan_guid,
                'operation': operation
            },
            **self.request_ads)
        self.assertEqual(HTTPStatus.OK, response.status_code)
        self.assertEqual('succeeded', response.json()['state'])

    def check_provision(self, instace_guid, org_guid, space_guid, service_guid, plan_guid):
        response = requests.put(
            "http://localhost:5001/v2/service_instances/{}?accepts_incomplete=true".format(instace_guid),
            data=json.dumps({
                "organization_guid": org_guid,
                "space_guid": space_guid,
                "service_id": service_guid,
                "plan_id": plan_guid,
                # "context": {
                #     "organization_guid": "org-guid-here",
                #     "space_guid": "space-guid-here",
                # }
            }),
            **self.request_ads)
        self.assertEqual(HTTPStatus.ACCEPTED, response.status_code)

        operation = response.json().get('operation')
        self.assertEqual('provision', operation)

        return operation

    def check_catalog(self, service_guid, plan_guid):
        response = requests.get('http://localhost:5001/v2/catalog', **self.request_ads)
        catalog = response.json()
        self.assertEqual(HTTPStatus.OK, response.status_code)
        # find service
        for service in catalog['services']:
            if service['name'] == 'InMemService':
                break
        else:
            service = None
        self.assertIsNotNone(service)
        self.assertEqual(service_guid, service.get('id'))

        # find plan
        for plan in service['plans']:
            if plan['name'] == 'standard':
                break
        else:
            plan = None
        self.assertIsNotNone(plan)
        self.assertEqual(plan_guid, plan.get('id'))

class InMemoryBroker(ServiceBroker):
    CREATING = 'CREATING'
    CREATED = 'CREATED'
    BINDING = 'BINDING'
    BOUND = 'BOUND'
    UNBINDING = 'UNBINDING'
    DELETING = 'DELETING'

    def __init__(self, service_guid, plan_guid):
        self.service_guid = service_guid
        self.plan_guid = plan_guid

        self.service_instances = dict()

    def catalog(self) -> Union[Service, List[Service]]:
        return Service(
            id=self.service_guid,
            name='InMemService',
            description='InMemService',
            bindable=True,
            plans=[
                ServicePlan(
                    id=self.plan_guid,
                    name='standard',
                    description='standard plan',
                    free=False,
                )
            ]
        )

    def provision(self,
                  instance_id: str,
                  details: ProvisionDetails,
                  async_allowed: bool,
                  **kwargs) -> ProvisionedServiceSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        self.service_instances[instance_id] = {
            'provision_details': details,
            'state': self.CREATING
        }

        return ProvisionedServiceSpec(
            state=ProvisionState.IS_ASYNC,
            operation='provision'
        )

    def bind(self, instance_id: str, binding_id: str, details: BindDetails, async_allowed: bool, **kwargs) -> Binding:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id, {})
        if instance and instance.get('state') == self.CREATED:
            instance['state'] = self.BINDING
            return Binding(BindState.IS_ASYNC, operation='bind')

    def unbind(self, instance_id: str, binding_id: str, details: UnbindDetails, async_allowed: bool,
               **kwargs) -> UnbindSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id, {})
        if instance and instance.get('state') == self.BOUND:
            instance['state'] = self.UNBINDING
            return UnbindSpec(True, 'unbind')

    def deprovision(self, instance_id: str, details: DeprovisionDetails, async_allowed: bool,
                    **kwargs) -> DeprovisionServiceSpec:
        if not async_allowed:
            raise errors.ErrAsyncRequired()

        instance = self.service_instances.get(instance_id)
        if instance is None:
            raise errors.ErrInstanceDoesNotExist()

        if instance.get('state') == self.CREATED:
            instance['state'] = self.DELETING
            return DeprovisionServiceSpec(True, 'deprovision')

    def last_operation(self, instance_id: str, operation_data: Optional[str], **kwargs) -> LastOperation:
        instance = self.service_instances.get(instance_id)
        if instance is None:
            raise errors.ErrInstanceDoesNotExist()

        if instance.get('state') == self.CREATING:
            instance['state'] = self.CREATED
            return LastOperation(OperationState.SUCCEEDED)
        elif instance.get('state') == self.DELETING:
            del self.service_instances[instance_id]
            raise errors.ErrInstanceDoesNotExist()

    def last_binding_operation(self,
                               instance_id: str,
                               binding_id: str,
                               operation_data: Optional[str],
                               **kwargs
                               ) -> LastOperation:
        instance = self.service_instances.get(instance_id, {})
        if instance.get('state') == self.BINDING:
            instance['state'] = self.BOUND
            return LastOperation(OperationState.SUCCEEDED)
        elif instance.get('state') == self.UNBINDING:
            instance['state'] = self.CREATED
            return LastOperation(OperationState.SUCCEEDED)
<|endoftext|>


<commit_before>
"""
Test incoming call handling.
"""

print "FIXME: jingle/test-incoming-call.py disabled due to race condition"
# exiting 77 causes automake to consider the test to have been skipped
raise SystemExit(77)

from gabbletest import exec_test, make_result_iq
from servicetest import make_channel_proxy, unwrap, tp_path_prefix
import jingletest
import gabbletest
import dbus
import time

def test(q, bus, conn, stream):
    jt = jingletest.JingleTest(stream, 'test@localhost', 'foo@bar.com/Foo')

    # If we need to override remote caps, feats, codecs or caps,
    # this is a good time to do it

    # Connecting
    conn.Connect()

    q.expect('dbus-signal', signal='StatusChanged', args=[1, 1])
    q.expect('stream-authenticated')
    q.expect('dbus-signal', signal='PresenceUpdate',
        args=[{1L: (0L, {u'available': {}})}])
    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    # We need remote end's presence for capabilities
    jt.send_remote_presence()

    # Gabble doesn't trust it, so makes a disco
    event = q.expect('stream-iq', query_ns='http://jabber.org/protocol/disco#info',
             to='foo@bar.com/Foo')

    jt.send_remote_disco_reply(event.stanza)

    remote_handle = conn.RequestHandles(1, ["foo@bar.com/Foo"])[0]

    # SCENARIO 1 - We reject incoming call

    # Remote end calls us
    jt.incoming_call()

    # The caller is in members
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [remote_handle], [], [], [], 0, 0])

    # S-E gets notified about new session handler, and calls Ready on it
    e = q.expect('dbus-signal', signal='NewSessionHandler')
    assert e.args[1] == 'rtp'

    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    # We're pending because of remote_handle
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [], [], [1L], [], remote_handle, 0])

    media_chan = make_channel_proxy(conn, tp_path_prefix + e.path, 'Channel.Interface.Group')

    media_chan.RemoveMembers([dbus.UInt32(1)], 'rejected')

    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'session-terminate'

    # SCENARIO 2 - We accept the call

    # FIXME - try to avoid this copy-paste

    # Remote end calls us
    jt.incoming_call()

    # The caller is in members
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [remote_handle], [], [], [], 0, 0])

    # S-E gets notified about new session handler, and calls Ready on it
    e = q.expect('dbus-signal', signal='NewSessionHandler')
    assert e.args[1] == 'rtp'

    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    # We're pending because of remote_handle
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [], [], [1L], [], remote_handle, 0])

    media_chan = make_channel_proxy(conn, tp_path_prefix + e.path, 'Channel.Interface.Group')

    media_chan.AddMembers([dbus.UInt32(1)], 'accepted')

    # S-E gets notified about a newly-created stream
    e = q.expect('dbus-signal', signal='NewStreamHandler')

    stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')

    stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
    stream_handler.Ready(jt.get_audio_codecs_dbus())
    stream_handler.StreamState(2)

    # First one is transport-info
    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'transport-info'
    assert e.query['initiator'] == 'foo@bar.com/Foo'

    stream.send(gabbletest.make_result_iq(stream, e.stanza))

    # Second one is session-accept
    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'session-accept'

    stream.send(gabbletest.make_result_iq(stream, e.stanza))

    # Connected! Blah, blah, ...

    # 'Nuff said
    jt.remote_terminate()

    # Tests completed, close the connection

    e = q.expect('dbus-signal', signal='Close') #XXX - match against the path

    conn.Disconnect()
    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])

    return True

if __name__ == '__main__':
    exec_test(test)

<commit_msg>test-incoming-call.py: check if we are moved the members when accepting the call<commit_after>
"""
Test incoming call handling.
"""

print "FIXME: jingle/test-incoming-call.py disabled due to race condition"
# exiting 77 causes automake to consider the test to have been skipped
raise SystemExit(77)

from gabbletest import exec_test, make_result_iq
from servicetest import make_channel_proxy, unwrap, tp_path_prefix
import jingletest
import gabbletest
import dbus
import time

def test(q, bus, conn, stream):
    jt = jingletest.JingleTest(stream, 'test@localhost', 'foo@bar.com/Foo')

    # If we need to override remote caps, feats, codecs or caps,
    # this is a good time to do it

    # Connecting
    conn.Connect()

    q.expect('dbus-signal', signal='StatusChanged', args=[1, 1])
    q.expect('stream-authenticated')
    q.expect('dbus-signal', signal='PresenceUpdate',
        args=[{1L: (0L, {u'available': {}})}])
    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    # We need remote end's presence for capabilities
    jt.send_remote_presence()

    # Gabble doesn't trust it, so makes a disco
    event = q.expect('stream-iq', query_ns='http://jabber.org/protocol/disco#info',
             to='foo@bar.com/Foo')

    jt.send_remote_disco_reply(event.stanza)

    remote_handle = conn.RequestHandles(1, ["foo@bar.com/Foo"])[0]

    # SCENARIO 1 - We reject incoming call

    # Remote end calls us
    jt.incoming_call()

    # The caller is in members
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [remote_handle], [], [], [], 0, 0])

    # S-E gets notified about new session handler, and calls Ready on it
    e = q.expect('dbus-signal', signal='NewSessionHandler')
    assert e.args[1] == 'rtp'

    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    # We're pending because of remote_handle
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [], [], [1L], [], remote_handle, 0])

    media_chan = make_channel_proxy(conn, tp_path_prefix + e.path, 'Channel.Interface.Group')

    media_chan.RemoveMembers([dbus.UInt32(1)], 'rejected')

    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'session-terminate'

    # SCENARIO 2 - We accept the call

    # FIXME - try to avoid this copy-paste

    # Remote end calls us
    jt.incoming_call()

    # The caller is in members
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [remote_handle], [], [], [], 0, 0])

    # S-E gets notified about new session handler, and calls Ready on it
    e = q.expect('dbus-signal', signal='NewSessionHandler')
    assert e.args[1] == 'rtp'

    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    # We're pending because of remote_handle
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [], [], [1L], [], remote_handle, 0])

    media_chan = make_channel_proxy(conn, tp_path_prefix + e.path, 'Channel.Interface.Group')

    media_chan.AddMembers([dbus.UInt32(1)], 'accepted')

    # S-E gets notified about a newly-created stream
    e = q.expect('dbus-signal', signal='NewStreamHandler')

    stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')

    # We are now in members too
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [1L], [], [], [], 0, 0])

    stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
    stream_handler.Ready(jt.get_audio_codecs_dbus())
    stream_handler.StreamState(2)

    # First one is transport-info
    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'transport-info'
    assert e.query['initiator'] == 'foo@bar.com/Foo'

    stream.send(gabbletest.make_result_iq(stream, e.stanza))

    # Second one is session-accept
    e = q.expect('stream-iq')
    assert e.query.name == 'jingle'
    assert e.query['action'] == 'session-accept'

    stream.send(gabbletest.make_result_iq(stream, e.stanza))

    # Connected! Blah, blah, ...

    # 'Nuff said
    jt.remote_terminate()

    # Tests completed, close the connection

    e = q.expect('dbus-signal', signal='Close') #XXX - match against the path

    conn.Disconnect()
    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])

    return True

if __name__ == '__main__':
    exec_test(test)

<|endoftext|>


<commit_before>
from contextlib import contextmanager
from operator import iand, ior
from uuid import uuid4
from redis import Redis
from redis.exceptions import ResponseError

redis = Redis()
_pipeline = None
client = lambda: _pipeline or redis

@contextmanager
def pipeline():
    global _pipeline
    _pipeline = redis.pipeline()
    yield
    _pipeline.execute()
    _pipeline = None

lua_funcs = {}
with open("atoms.lua", "r") as f:
    for func in f.read().strip().split("function "):
        if not func:
            continue
        name, code = func.split("\n", 1)
        name = name.split("(")[0].strip()
        code = code.rsplit("end", 1)[0].strip()
        lua_funcs[name] = redis.register_script(code)

class Base(object):

    def __init__(self, value=None, key=None):
        self.key = key or str(uuid4())

    def __del__(self):
        self.delete()

    def _proxy(self, name):
        try:
            func = getattr(client(), name)
        except AttributeError:
            pass
        else:
            return lambda *a, **k: func(self.key, *a, **k)
        try:
            func = lua_funcs[name]
        except KeyError:
            pass
        else:
            return lambda *a, **k: func(keys=[self.key], args=a, **k)
        raise AttributeError(name)

    def __getattr__(self, name):
        return self._proxy(name)

    def __repr__(self):
        return "%s" % self.value

class Iterable(Base):

    def __init__(self, value=None, key=None):
        super(Iterable, self).__init__(value, key)
        self.type = None

    def _proxy(self, name):
        func = super(Iterable, self)._proxy(name)
        def wrapper(*args, **kwargs):
            value = func(*args, **kwargs)
            if value is not None:
                return self._set_type(value)
        return wrapper

    def _to_value(self, value):
        if type(value) == type(self):
            return value.value
        return value

    def _is_many(self, value):
        return type(value).__name__ == type(self).__name__.lower()

    def _set_type(self, value):
        if self.type == str:
            return value
        elif self._is_many(value):
            typed_value = map(self._set_type, value)
            if type(typed_value) != type(value):
                # Everything other than lists.
                typed_value = type(value)(typed_value)
            return typed_value
        elif self.type:
            return self.type(value)
        return value

    def _check_type(self, value):
        if self._is_many(value):
            map(self._check_type, value)
        else:
            t = type(value)
            if not self.type:
                self.type = t
            elif t != self.type:
                raise TypeError("%s != %s" % (t, self.type))

class List(Iterable):

    def __init__(self, value=None, key=None):
        super(List, self).__init__(value, key)
        if not isinstance(value, list):
            try:
                list(value)
            except TypeError:
                value = None
        if value:
            self.extend(value)

    @property
    def value(self):
        return self[:]

    def __eq__(self, l):
        return self.value == self._to_value(l)

    def __iter__(self):
        return iter(self.value)

    def __add__(self, l):
        return List(self.value + self._to_value(l))

    def __iadd__(self, l):
        self.extend(self._to_value(l))
        return self

    def __mul__(self, i):
        return List(self.value * i)

    def __imul__(self, i):
        self.list_multiply(i)
        return self

    def __len__(self):
        return self.llen()

    def __getitem__(self, i):
        if isinstance(i, slice):
            start = i.start if i.start is not None else 0
            stop = i.stop if i.stop is not None else -1
            return self.lrange(start, stop)
        item = self.lindex(i)
        if item is None:
            raise IndexError
        return item

    def __setitem__(self, i, value):
        self._check_type(value)
        try:
            self.lset(i, value)
        except ResponseError:
            raise IndexError

    def __delitem__(self, i):
        self.pop(i)

    def extend(self, l):
        self._check_type(l)
        self.rpush(*l)

    def append(self, value):
        self.extend([value])

    def insert(self, i, value):
        self._check_type(value)
        self.list_insert(i, value)

    def pop(self, i=-1):
        if i == -1:
            return self.rpop()
        elif i == 0:
            return self.lpop()
        else:
            return self.list_pop(i)

    def reverse(self):
        self.list_reverse()

    def index(self, value):
        return self.value.index(value)

    def count(self, value):
        return self.value.count(value)

    def sort(self, reverse=False):
        self._proxy("sort")(desc=reverse, store=self.key)

class Set(Iterable):

    def __init__(self, value=None, key=None):
        super(Set, self).__init__(value, key)
        self.type = None
        try:
            iter(value)
        except TypeError:
            value = None
        if value:
            self.update(value)

    @property
    def value(self):
        return self.smembers()

    def _all_redis(self, values):
        return all([isinstance(value, Set) for value in values])

    def _reduce(self, op, values):
        for i, value in enumerate(values):
            self._check_type(set(value))
            value = [v.value if isinstance(v, Set) else v for v in value]
        return reduce(op, values)

    def add(self, value):
        self.update([value])

    def update(self, *values):
        self.sadd(*self._reduce(ior, values))

    def pop(self):
        return self.spop()

    def clear(self):
        del self

    def remove(self):
        if self.srem(value) == 0:
            raise KeyError

    def discard(self, value):
        self.srem(value)

    def __len__(self, value):
        return self.scard()

    def __contains__(self, value):
        return self.sismember(value)

    def __and__(self, *values):
        if self._all_redis(values):
            keys = [value.key for value in values]
            return self.sinter(*keys)
        else:
            return self._reduce(iand, (self.value,) + values)

    def __iand__(self, *values):
        if self._all_redis(values):
            keys = [value.key for value in values]
            self.sinterstore(self.key, *keys)
        else:
            values = list(self._reduce(iand, values))
            self.set_intersection_update(*values)
        return self

    def __rand__(self, value):
        return value & self

    def intersection(self, value):
        return self & value

    def intersection_update(self, value):
        self &= value
        return self

    def __or__(self, value):
        raise NotImplemented
    def __ior__(self, value):
        raise NotImplemented
    def __ror__(self, value):
        raise NotImplemented
    def union(self, value):
        raise NotImplemented

    def __xor__(self, value):
        raise NotImplemented
    def symmetric_difference(self, value):
        raise NotImplemented
    def symmetric_difference_update(self, value):
        raise NotImplemented

    def __sub__(self, value):
        raise NotImplemented
    def __isub__(self, value):
        raise NotImplemented
    def __rsub__(self, value):
        raise NotImplemented
    def difference(self, value):
        raise NotImplemented

    def issubset(self, value):
        raise NotImplemented
    def issuperset(self, value):
        raise NotImplemented
    def isdisjoint(self, value):
        raise NotImplemented

class Dict(Iterable):

    def __init__(self, value=None, key=None):
        super(Dict, self).__init__(value, key)
        if not isinstance(value, dict):
            try:
                value = dict(value)
            except TypeError:
                value = None
        if value:
            self.update(value)

    @property
    def value(self):
        return self.hgetall()

    def update(self, value):
        self.hmset(value)

    def keys(self):
        return self.hkeys()

    def values(self):
        return self.values()

    def items(self):
        return self.value.items()

    def setdefault(self, name, value=None):
        if self.hsetnx(name, value) == 1:
            return value

    def get(self, name, default=None):
        return self.hget(name) or default

    def __getitem__(self, name):
        value = self.get(name)
        if value is None:
            raise KeyError

    def __setitem__(self, name, value):
        self.hset(name)

    def __delitem__(self, name):
        self.hdel(name)
<commit_msg>Fix list slicing<commit_after>
from contextlib import contextmanager
from operator import iand, ior
from uuid import uuid4
from redis import Redis
from redis.exceptions import ResponseError

redis = Redis()
_pipeline = None
client = lambda: _pipeline or redis

@contextmanager
def pipeline():
    global _pipeline
    _pipeline = redis.pipeline()
    yield
    _pipeline.execute()
    _pipeline = None

lua_funcs = {}
with open("atoms.lua", "r") as f:
    for func in f.read().strip().split("function "):
        if not func:
            continue
        name, code = func.split("\n", 1)
        name = name.split("(")[0].strip()
        code = code.rsplit("end", 1)[0].strip()
        lua_funcs[name] = redis.register_script(code)

class Base(object):

    def __init__(self, value=None, key=None):
        self.key = key or str(uuid4())

    def __del__(self):
        self.delete()

    def _proxy(self, name):
        try:
            func = getattr(client(), name)
        except AttributeError:
            pass
        else:
            return lambda *a, **k: func(self.key, *a, **k)
        try:
            func = lua_funcs[name]
        except KeyError:
            pass
        else:
            return lambda *a, **k: func(keys=[self.key], args=a, **k)
        raise AttributeError(name)

    def __getattr__(self, name):
        return self._proxy(name)

    def __repr__(self):
        return "%s" % self.value

class Iterable(Base):

    def __init__(self, value=None, key=None):
        super(Iterable, self).__init__(value, key)
        self.type = None

    def _proxy(self, name):
        func = super(Iterable, self)._proxy(name)
        def wrapper(*args, **kwargs):
            value = func(*args, **kwargs)
            if value is not None:
                return self._set_type(value)
        return wrapper

    def _to_value(self, value):
        if type(value) == type(self):
            return value.value
        return value

    def _is_many(self, value):
        return type(value).__name__ == type(self).__name__.lower()

    def _set_type(self, value):
        if self.type == str:
            return value
        elif self._is_many(value):
            typed_value = map(self._set_type, value)
            if type(typed_value) != type(value):
                # Everything other than lists.
                typed_value = type(value)(typed_value)
            return typed_value
        elif self.type:
            return self.type(value)
        return value

    def _check_type(self, value):
        if self._is_many(value):
            map(self._check_type, value)
        else:
            t = type(value)
            if not self.type:
                self.type = t
            elif t != self.type:
                raise TypeError("%s != %s" % (t, self.type))

class List(Iterable):

    def __init__(self, value=None, key=None):
        super(List, self).__init__(value, key)
        if not isinstance(value, list):
            try:
                list(value)
            except TypeError:
                value = None
        if value:
            self.extend(value)

    @property
    def value(self):
        return self[:]

    def __eq__(self, l):
        return self.value == self._to_value(l)

    def __iter__(self):
        return iter(self.value)

    def __add__(self, l):
        return List(self.value + self._to_value(l))

    def __iadd__(self, l):
        self.extend(self._to_value(l))
        return self

    def __mul__(self, i):
        return List(self.value * i)

    def __imul__(self, i):
        self.list_multiply(i)
        return self

    def __len__(self):
        return self.llen()

    def __getitem__(self, i):
        if isinstance(i, slice):
            start = i.start if i.start is not None else 0
            stop = i.stop if i.stop is not None else 0
            return self.lrange(start, stop - 1)
        item = self.lindex(i)
        if item is None:
            raise IndexError
        return item

    def __setitem__(self, i, value):
        self._check_type(value)
        try:
            self.lset(i, value)
        except ResponseError:
            raise IndexError

    def __delitem__(self, i):
        self.pop(i)

    def extend(self, l):
        self._check_type(l)
        self.rpush(*l)

    def append(self, value):
        self.extend([value])

    def insert(self, i, value):
        self._check_type(value)
        self.list_insert(i, value)

    def pop(self, i=-1):
        if i == -1:
            return self.rpop()
        elif i == 0:
            return self.lpop()
        else:
            return self.list_pop(i)

    def reverse(self):
        self.list_reverse()

    def index(self, value):
        return self.value.index(value)

    def count(self, value):
        return self.value.count(value)

    def sort(self, reverse=False):
        self._proxy("sort")(desc=reverse, store=self.key)

class Set(Iterable):

    def __init__(self, value=None, key=None):
        super(Set, self).__init__(value, key)
        self.type = None
        try:
            iter(value)
        except TypeError:
            value = None
        if value:
            self.update(value)

    @property
    def value(self):
        return self.smembers()

    def _all_redis(self, values):
        return all([isinstance(value, Set) for value in values])

    def _reduce(self, op, values):
        for i, value in enumerate(values):
            self._check_type(set(value))
            value = [v.value if isinstance(v, Set) else v for v in value]
        return reduce(op, values)

    def add(self, value):
        self.update([value])

    def update(self, *values):
        self.sadd(*self._reduce(ior, values))

    def pop(self):
        return self.spop()

    def clear(self):
        del self

    def remove(self):
        if self.srem(value) == 0:
            raise KeyError

    def discard(self, value):
        self.srem(value)

    def __len__(self, value):
        return self.scard()

    def __contains__(self, value):
        return self.sismember(value)

    def __and__(self, *values):
        if self._all_redis(values):
            keys = [value.key for value in values]
            return self.sinter(*keys)
        else:
            return self._reduce(iand, (self.value,) + values)

    def __iand__(self, *values):
        if self._all_redis(values):
            keys = [value.key for value in values]
            self.sinterstore(self.key, *keys)
        else:
            values = list(self._reduce(iand, values))
            self.set_intersection_update(*values)
        return self

    def __rand__(self, value):
        return value & self

    def intersection(self, value):
        return self & value

    def intersection_update(self, value):
        self &= value
        return self

    def __or__(self, value):
        raise NotImplemented
    def __ior__(self, value):
        raise NotImplemented
    def __ror__(self, value):
        raise NotImplemented
    def union(self, value):
        raise NotImplemented

    def __xor__(self, value):
        raise NotImplemented
    def symmetric_difference(self, value):
        raise NotImplemented
    def symmetric_difference_update(self, value):
        raise NotImplemented

    def __sub__(self, value):
        raise NotImplemented
    def __isub__(self, value):
        raise NotImplemented
    def __rsub__(self, value):
        raise NotImplemented
    def difference(self, value):
        raise NotImplemented

    def issubset(self, value):
        raise NotImplemented
    def issuperset(self, value):
        raise NotImplemented
    def isdisjoint(self, value):
        raise NotImplemented

class Dict(Iterable):

    def __init__(self, value=None, key=None):
        super(Dict, self).__init__(value, key)
        if not isinstance(value, dict):
            try:
                value = dict(value)
            except TypeError:
                value = None
        if value:
            self.update(value)

    @property
    def value(self):
        return self.hgetall()

    def update(self, value):
        self.hmset(value)

    def keys(self):
        return self.hkeys()

    def values(self):
        return self.values()

    def items(self):
        return self.value.items()

    def setdefault(self, name, value=None):
        if self.hsetnx(name, value) == 1:
            return value

    def get(self, name, default=None):
        return self.hget(name) or default

    def __getitem__(self, name):
        value = self.get(name)
        if value is None:
            raise KeyError

    def __setitem__(self, name, value):
        self.hset(name)

    def __delitem__(self, name):
        self.hdel(name)
<|endoftext|>


<commit_before>from datetime import datetime

from django.db import models
from django.contrib.auth.models import User

from eve_api.models import EVEPlayerCharacter, EVEPlayerCorporation

from hr.app_defines import *

class Application(models.Model):
    user = models.ForeignKey(User, blank=False, verbose_name="User")
    character = models.ForeignKey(EVEPlayerCharacter, blank=False, verbose_name="Character")
    corporation = models.ForeignKey(EVEPlayerCorporation, blank=False, verbose_name="Applying to Corporation")
    status = models.IntegerField(choices=APPLICATION_STATUS_CHOICES,
                                     default=APPLICATION_STATUS_NOTSUBMITTED,
                                     verbose_name="Status",
                                     help_text="Current status of this application request.")

    @property
    def blacklisted(self):
        if len(self.blacklist_values) > 0:
            return True
        return False

    @property
    def blacklist_values(self):
        """
        Returns a list of blacklist values that apply to the application
        """

        blacklist = []

        bl_items = Blacklist.objects.filter( models.Q(expiry_date__gt=datetime.now()) | models.Q(expiry_date=None) )

        # Check Reddit blacklists
        reddit_uids = self.user.redditaccount_set.all().values_list('username')
        reddit = [a[0].lower() for a in reddit_uids if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_REDDIT, value__in=reddit)
        blacklist.extend(objs)

        # Check email blacklists
        blacklist.extend(bl_items.filter(type=BLACKLIST_TYPE_EMAIL, value=self.user.email.lower()))

        # Check Auth blacklists
        blacklist.extend(bl_items.filter(type=BLACKLIST_TYPE_AUTH, value=self.user.username.lower()))

        # Check EVE Related blacklists
        evechars = EVEPlayerCharacter.objects.filter(eveaccount__user=self.user).select_related('corporation__alliance')

        # Check Character blacklists
        chars = [a[0].lower() for a in evechars.values_list('name') if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_CHARACTER, value__in=chars)
        blacklist.extend(objs)

        # Check Corporation blacklists
        corps = [a[0].lower() for a in evechars.values_list('corporation__name') if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_CORPORATION, value__in=corps)
        blacklist.extend(objs)

        # Check Alliance blacklists
        alliances = [a[0].lower() for a in evechars.values_list('corporation__alliance__name') if a and a[0]]

        objs = bl_items.filter(type=BLACKLIST_TYPE_ALLIANCE, value__in=alliances)
        blacklist.extend(objs)

        return blacklist

    def save(self, *args, **kwargs):
        try:
            old_instance = Application.objects.get(id=self.id)
            if not (old_instance.status == int(self.status)):
                event = Audit(application=self)
                if 'user' in kwargs:
                    event.user = kwargs['user']
                event.event = AUDIT_EVENT_STATUSCHANGE

                event.text = "Status changed from %s to %s" % (old_instance.get_status_display(), self.get_status_display())
                event.save()
        except:
            pass

        if 'user' in kwargs:
            del kwargs['user']
        super(Application, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.character.name

    def __str__(self):
        return self.__unicode__()

class Recommendation(models.Model):
    user = models.ForeignKey(User, blank=False, verbose_name="User")
    user_character = models.ForeignKey(EVEPlayerCharacter, blank=False, verbose_name="Recommender")
    application = models.ForeignKey(Application, blank=False, verbose_name="Recommended Application")

    def __unicode__(self):
        return self.user_character.name

    def __str__(self):
        return self.__unicode__()

class Audit(models.Model):
    application = models.ForeignKey(Application, blank=False, verbose_name="Application")
    user = models.ForeignKey(User, blank=True, verbose_name="User")
    event = models.IntegerField(choices=AUDIT_EVENT_CHOICES,
                                     verbose_name="Event Type",
                                     help_text="Type of audit event")
    text = models.TextField(blank=False, verbose_name="Event Text",
                                     help_text="Detailed event text")

    date = models.DateTimeField(auto_now_add=True, verbose_name="Event Date")

class Blacklist(models.Model):
    type = models.IntegerField(choices=BLACKLIST_TYPE_CHOICES,
                                     verbose_name="Blacklisted Type",
                                     help_text="Type of entity to be blacklisted")
    value = models.CharField("Blacklisted Value", max_length=255, blank=False)
    reason = models.TextField(blank=False, verbose_name="Reason",
                                     help_text="Reason that the entity was blacklisted")

    expiry_date = models.DateTimeField(verbose_name="Expiry Date", blank=False, null=True,
                                     help_text="Date to expire this entry")

    created_date = models.DateTimeField(auto_now_add=True, verbose_name="Created Date")
    created_by = models.ForeignKey(User, blank=False, verbose_name="Created By")

    def __unicode__(self):
        return u'%s: %s' % (self.get_type_display(), self.value)

    def __str__(self):
        return self.__unicode__()
<commit_msg>Fixes the HR message issue when changing status<commit_after>from datetime import datetime

from django.db import models
from django.contrib.auth.models import User

from eve_api.models import EVEPlayerCharacter, EVEPlayerCorporation

from hr.app_defines import *

class Application(models.Model):
    user = models.ForeignKey(User, blank=False, verbose_name="User")
    character = models.ForeignKey(EVEPlayerCharacter, blank=False, verbose_name="Character")
    corporation = models.ForeignKey(EVEPlayerCorporation, blank=False, verbose_name="Applying to Corporation")
    status = models.IntegerField(choices=APPLICATION_STATUS_CHOICES,
                                     default=APPLICATION_STATUS_NOTSUBMITTED,
                                     verbose_name="Status",
                                     help_text="Current status of this application request.")

    @property
    def blacklisted(self):
        if len(self.blacklist_values) > 0:
            return True
        return False

    @property
    def blacklist_values(self):
        """
        Returns a list of blacklist values that apply to the application
        """

        blacklist = []

        bl_items = Blacklist.objects.filter( models.Q(expiry_date__gt=datetime.now()) | models.Q(expiry_date=None) )

        # Check Reddit blacklists
        reddit_uids = self.user.redditaccount_set.all().values_list('username')
        reddit = [a[0].lower() for a in reddit_uids if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_REDDIT, value__in=reddit)
        blacklist.extend(objs)

        # Check email blacklists
        blacklist.extend(bl_items.filter(type=BLACKLIST_TYPE_EMAIL, value=self.user.email.lower()))

        # Check Auth blacklists
        blacklist.extend(bl_items.filter(type=BLACKLIST_TYPE_AUTH, value=self.user.username.lower()))

        # Check EVE Related blacklists
        evechars = EVEPlayerCharacter.objects.filter(eveaccount__user=self.user).select_related('corporation__alliance')

        # Check Character blacklists
        chars = [a[0].lower() for a in evechars.values_list('name') if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_CHARACTER, value__in=chars)
        blacklist.extend(objs)

        # Check Corporation blacklists
        corps = [a[0].lower() for a in evechars.values_list('corporation__name') if a and a[0]]
        objs = bl_items.filter(type=BLACKLIST_TYPE_CORPORATION, value__in=corps)
        blacklist.extend(objs)

        # Check Alliance blacklists
        alliances = [a[0].lower() for a in evechars.values_list('corporation__alliance__name') if a and a[0]]

        objs = bl_items.filter(type=BLACKLIST_TYPE_ALLIANCE, value__in=alliances)
        blacklist.extend(objs)

        return blacklist

    def save(self, *args, **kwargs):

        user = None
        if 'user' in kwargs:
            user = kwargs['user']
            del kwargs['user']

        try:
            old_instance = Application.objects.get(id=self.id)
            if not (old_instance.status == int(self.status)):
                event = Audit(application=self)
                event.user = user
                event.event = AUDIT_EVENT_STATUSCHANGE

                # Save the application so we can get a up to date status
                super(Application, self).save(*args, **kwargs)
                new_instance = Application.objects.get(id=self.id)

                event.text = "Status changed from %s to %s" % (old_instance.get_status_display(), new_instance.get_status_display())
                event.save()
        except:
            pass

        super(Application, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.character.name

    def __str__(self):
        return self.__unicode__()

class Recommendation(models.Model):
    user = models.ForeignKey(User, blank=False, verbose_name="User")
    user_character = models.ForeignKey(EVEPlayerCharacter, blank=False, verbose_name="Recommender")
    application = models.ForeignKey(Application, blank=False, verbose_name="Recommended Application")

    def __unicode__(self):
        return self.user_character.name

    def __str__(self):
        return self.__unicode__()

class Audit(models.Model):
    application = models.ForeignKey(Application, blank=False, verbose_name="Application")
    user = models.ForeignKey(User, blank=True, verbose_name="User")
    event = models.IntegerField(choices=AUDIT_EVENT_CHOICES,
                                     verbose_name="Event Type",
                                     help_text="Type of audit event")
    text = models.TextField(blank=False, verbose_name="Event Text",
                                     help_text="Detailed event text")

    date = models.DateTimeField(auto_now_add=True, verbose_name="Event Date")

class Blacklist(models.Model):
    type = models.IntegerField(choices=BLACKLIST_TYPE_CHOICES,
                                     verbose_name="Blacklisted Type",
                                     help_text="Type of entity to be blacklisted")
    value = models.CharField("Blacklisted Value", max_length=255, blank=False)
    reason = models.TextField(blank=False, verbose_name="Reason",
                                     help_text="Reason that the entity was blacklisted")

    expiry_date = models.DateTimeField(verbose_name="Expiry Date", blank=False, null=True,
                                     help_text="Date to expire this entry")

    created_date = models.DateTimeField(auto_now_add=True, verbose_name="Created Date")
    created_by = models.ForeignKey(User, blank=False, verbose_name="Created By")

    def __unicode__(self):
        return u'%s: %s' % (self.get_type_display(), self.value)

    def __str__(self):
        return self.__unicode__()
<|endoftext|>


<commit_before># Local settings for server_proj project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG
JSON_PRETTY_PRINT = False

OAUTH_AUTHORIZE_VIEW = 'spotseeker_server.views.oauth.authorize'
OAUTH_CALLBACK_VIEW = 'spotseeker_server.views.oauth.callback'

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

MANAGERS = ADMINS

LABSTATS_URL = ""

# Values can be one of 'all_ok' or 'oauth'. If using 'oauth', client applications will need an oauth key/secret pair.
SPOTSEEKER_AUTH_MODULE = 'spotseeker_server.auth.all_ok'
#SPOTSEEKER_AUTH_MODULE = 'spotseeker_server.auth.oauth'
SPOTSEEKER_AUTH_ADMINS = ()

# Custom validation can be added by adding SpotForm and ExtendedInfoForm to org_forms and setting them here.
SPOTSEEKER_SPOT_FORM = 'spotseeker_server.org_forms.uw_spot.UWSpotForm'
SPOTSEEKER_SPOTEXTENDEDINFO_FORM = 'spotseeker_server.org_forms.uw_spot.UWSpotExtendedInfoForm'
SPOTSEEKER_SEARCH_FILTERS = ['spotseeker_server.org_filters.uw_search.Filter']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'server.db',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Los_Angeles'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will not format dates, numbers and
# calendars accoring to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = 'http://localhost:8000/media/'

# Absolute path to the directory static files should be collected tp.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'

# Additional locations for static files
STATICFILES_DIRS = (
    # Put strings here
    # Always use forward slashes, even on Windows
    # Don't forget to use absolute
)

# List of finder classes that know how to find static files in
#various locations.
STATICFILES_FINDER = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    #'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '{{ server_key }}'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    #'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    #'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    #Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 'django.middleware.cache.FetchFromCacheMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackend',
)

ROOT_URLCONF = 'serverproject.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'serverproject.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "home/html/django_templates"
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths
)

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'sposeeker_server'
    }
}

CACHE_MIDDLEWARE_SECONDS = 60 * 60 # Cache what we can for an hour

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.admindocs',
    'south',
    'spotseeker_server',
    'oauth_provider',
)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    # 'loggers': {
    #     'django.request': {
    #         'handlers': ['mail_admin'],
    #         'level': 'ERROR',
    #         'propagate': True,
    #     },
    # }
}

# Preferred web app hostname
SS_APP_SERVER = 'spotseeker-test.uw.edu'

# Path used by web app to display a space
SS_APP_SPACE_PATH = "/space/{% raw %}{{ spot_id }}{% endraw %}/{% raw %}{{ spot_name }}{% endraw %}"
<commit_msg>Send all logging for the server to the console in development.<commit_after># Local settings for server_proj project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG
JSON_PRETTY_PRINT = False

OAUTH_AUTHORIZE_VIEW = 'spotseeker_server.views.oauth.authorize'
OAUTH_CALLBACK_VIEW = 'spotseeker_server.views.oauth.callback'

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

MANAGERS = ADMINS

LABSTATS_URL = ""

# Values can be one of 'all_ok' or 'oauth'. If using 'oauth', client applications will need an oauth key/secret pair.
SPOTSEEKER_AUTH_MODULE = 'spotseeker_server.auth.all_ok'
#SPOTSEEKER_AUTH_MODULE = 'spotseeker_server.auth.oauth'
SPOTSEEKER_AUTH_ADMINS = ()

# Custom validation can be added by adding SpotForm and ExtendedInfoForm to org_forms and setting them here.
SPOTSEEKER_SPOT_FORM = 'spotseeker_server.org_forms.uw_spot.UWSpotForm'
SPOTSEEKER_SPOTEXTENDEDINFO_FORM = 'spotseeker_server.org_forms.uw_spot.UWSpotExtendedInfoForm'
SPOTSEEKER_SEARCH_FILTERS = ['spotseeker_server.org_filters.uw_search.Filter']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'server.db',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Los_Angeles'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will not format dates, numbers and
# calendars accoring to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = 'http://localhost:8000/media/'

# Absolute path to the directory static files should be collected tp.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'

# Additional locations for static files
STATICFILES_DIRS = (
    # Put strings here
    # Always use forward slashes, even on Windows
    # Don't forget to use absolute
)

# List of finder classes that know how to find static files in
#various locations.
STATICFILES_FINDER = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    #'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '{{ server_key }}'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    #'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    #'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    #Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 'django.middleware.cache.FetchFromCacheMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackend',
)

ROOT_URLCONF = 'serverproject.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'serverproject.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "home/html/django_templates"
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths
)

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'sposeeker_server'
    }
}

CACHE_MIDDLEWARE_SECONDS = 60 * 60 # Cache what we can for an hour

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.admindocs',
    'south',
    'spotseeker_server',
    'oauth_provider',
)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
        'null': {
            'class': 'logging.NullHandler',
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        },
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}

# Preferred web app hostname
SS_APP_SERVER = 'spotseeker-test.uw.edu'

# Path used by web app to display a space
SS_APP_SPACE_PATH = "/space/{% raw %}{{ spot_id }}{% endraw %}/{% raw %}{{ spot_name }}{% endraw %}"
<|endoftext|>


<commit_before>import os
import sh
import tempfile
from contextlib import contextmanager

from ce.common import cached, timeit
import ce.logger as logger

class FlopocoMissingImplementationError(Exception):
    """Unsynthesizable operator"""

we_min, we_max = 5, 15
wf_min, wf_max = 10, 112
we_range = list(range(we_min, we_max + 1))
wf_range = list(range(wf_min, wf_max + 1))

directory = 'ce/semantics/'
default_file = directory + 'area.pkl'
template_file = directory + 'template.vhdl'

device_name = 'Virtex6'
device_model = 'xc6vlx760'

@contextmanager
def cd(d):
    p = os.path.abspath(os.curdir)
    if d:
        sh.mkdir('-p', d)
        sh.cd(d)
    try:
        yield
    except Exception:
        raise
    finally:
        sh.cd(p)

def get_luts(file_name):
    from bs4 import BeautifulSoup
    with open(file_name, 'r') as f:
        f = BeautifulSoup(f.read())
        app = f.document.application
        util = app.find('section', stringid='XST_DEVICE_UTILIZATION_SUMMARY')
        luts = util.find('item', stringid='XST_NUMBER_OF_SLICE_LUTS')
        return luts.get('value')

def flopoco(op, we, wf, f=None, dir=None):
    from ce.expr import ADD_OP, MULTIPLY_OP
    flopoco_cmd = []
    flopoco_cmd += ['-target=' + device_name]
    dir = dir or tempfile.mktemp(suffix='/')
    with cd(dir):
        if f is None:
            f = tempfile.mktemp(suffix='.vhdl')
        flopoco_cmd += ['-outputfile=%s' % f]
        if op == 'add' or op == ADD_OP:
            flopoco_cmd += ['FPAdder', we, wf]
        elif op == 'mul' or op == MULTIPLY_OP:
            flopoco_cmd += ['FPMultiplier', we, wf, wf]
        else:
            raise ValueError('Unrecognised operator %s' % str(op))
        sh.flopoco(*flopoco_cmd)
        try:
            with open(f) as fh:
                if not fh.read():
                    raise IOError()
        except (IOError, FileNotFoundError):
            logger.error('Flopoco failed to generate file %s' % f)
            raise
    return dir, f

def xilinx(f, dir=None):
    file_base = os.path.split(f)[1]
    file_base = os.path.splitext(file_base)[0]
    g = file_base + '.ngc'
    cmd = ['run', '-p', device_model]
    cmd += ['-ifn', f, '-ifmt', 'VHDL']
    cmd += ['-ofn', g, '-ofmt', 'NGC']
    dir = dir or tempfile.mktemp(suffix='/')
    with cd(dir):
        sh.xst(sh.echo(*cmd), _out='out.log', _err='err.log')
        return get_luts(file_base + '.ngc_xst.xrpt')

def eval_operator(op, we, wf, f=None, dir=None):
    dir, f = flopoco(op, we, wf, f, dir)
    return dict(op=op, we=we, wf=wf, value=xilinx(f, dir))

@timeit
def _para_synth(op_we_wf):
    op, we, wf = op_we_wf
    logger.info('Processing', op, we, wf)
    work_dir = 'syn_%d' % os.getpid()
    try:
        item = eval_operator(op, we, wf, f=None, dir=work_dir)
        logger.info('Processed', item)
        return item
    except sh.ErrorReturnCode:
        logger.error('Error processing %s, %d, %d' % op_we_wf)

pool = None

@timeit
def batch_synth(we_range, wf_range):
    import itertools
    from multiprocessing import Pool
    global pool
    if not pool:
        pool = Pool(8)
    args = itertools.product(['add', 'mul'], we_range, wf_range)
    return list(pool.imap_unordered(_para_synth, args))

def load(file_name):
    import pickle
    with open(file_name, 'rb') as f:
        return pickle.loads(f.read())

def save(file_name, results):
    import pickle
    results = [i for i in results if not i is None]
    with open(file_name, 'wb') as f:
        pickle.dump(results, f)

def plot(results):
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    fig = plt.figure()
    ax = Axes3D(fig)
    vl = []
    for i in results:
        xv, yv, zv = int(i['we']), int(i['wf']), int(i['value'])
        if zv < 0:
            continue
        vl.append((xv, yv, zv))
    ax.scatter(*zip(*vl))
    plt.show()

if not os.path.isfile(default_file):
    logger.warning('area statistics file does not exist, synthesizing...')
    save(default_file, batch_synth(we_range, wf_range))

_add = {}
_mul = {}
for i in load(default_file):
    xv, yv, zv = int(i['we']), int(i['wf']), int(i['value'])
    if zv <= 0:
        continue
    if i['op'] == 'add':
        _add[xv, yv] = zv
    elif i['op'] == 'mul':
        _mul[xv, yv] = zv

def _impl(_dict, we, wf):
    try:
        return _dict[we, wf]
    except KeyError:
        if not wf in wf_range:
            raise FlopocoMissingImplementationError(
                'Precision %d out of range' % wf)
        elif not we in we_range:
            raise FlopocoMissingImplementationError(
                'Exponent width %d out of range' % we)
        return _impl(_dict, we + 1, wf)

def adder(we, wf):
    return _impl(_add, we, wf)

def multiplier(we, wf):
    return _impl(_mul, we, wf)

@cached
def keys():
    return sorted(list(set(_add.keys()) & set(_mul.keys())))

class CodeGenerator(object):

    def __init__(self, expr, var_env, prec, file_name=None, dir=None):
        from ce.expr import Expr
        self.expr = Expr(expr)
        self.var_env = var_env
        self.wf = prec
        self.we = self.expr.exponent_width(var_env, prec)
        self.dir = dir or tempfile.mktemp(suffix='/')
        with cd(self.dir):
            self.f = file_name or tempfile.mktemp(suffix='.vhdl', dir=dir)

    def generate(self):
        from akpytemp import Template

        ops = set()
        in_ports = set()
        out_port, ls = self.expr.as_labels()
        wires = set()
        signals = set()

        def wire(op, in1, in2, out):
            def wire_name(i):
                if i in signals:
                    return i.signal_name()
                if i in in_ports:
                    return i.port_name()
                if i == out_port:
                    return 'p_out'
            for i in [in1, in2, out]:
                # a variable represented as a string is a port
                if isinstance(i.e, str):
                    in_ports.add(i)
                    continue
                # a number is a port
                try:
                    float(i.e)
                    in_ports.add(i)
                    continue
                except (TypeError, ValueError):
                    pass
                # a range is a port
                try:
                    a, b = i.e
                    float(a), float(b)
                    in_ports.add(i)
                    continue
                except (TypeError, ValueError):
                    pass
                # an expression, need a signal for its output
                try:
                    i.e.op
                    if i != out_port:
                        signals.add(i)
                except AttributeError:
                    pass
            wires.add((op, wire_name(in1), wire_name(in2), wire_name(out)))

        for out, e in ls.items():
            try:
                op, in1, in2 = e.op, e.a1, e.a2
                wire(op, in1, in2, out)
                ops.add(e.op)
            except AttributeError:
                pass
        in_ports = [i.port_name() for i in in_ports]
        out_port = 'p_out'
        signals = [i.signal_name() for i in signals]
        logger.debug(in_ports, signals, wires)
        Template(path=template_file).save(
            path=self.f, directory=self.dir, flopoco=flopoco,
            ops=ops, e=self.expr,
            we=self.we, wf=self.wf,
            in_ports=in_ports, out_port=out_port,
            signals=signals, wires=wires)
        return self.f

def eval_expr(expr, var_env, prec):
    dir = tempfile.mktemp(suffix='/')
    f = CodeGenerator(expr, var_env, prec, dir=dir).generate()
    logger.debug('Synthesising', f)
    return xilinx(f, dir=dir)

if __name__ == '__main__':
    from ce.expr import Expr
    logger.set_context(level=logger.levels.info)
    p = 23
    e = Expr('a + b + c')
    v = {'a': ['0', '1'], 'b': ['0', '100'], 'c': ['0', '100000']}
    logger.info(e.area(v, p).area)
    logger.info(e.real_area(v, p))
    plot(load(default_file))
<commit_msg>Minor changes to pool variable<commit_after>import os
import sh
import tempfile
from contextlib import contextmanager

from ce.common import cached, timeit
import ce.logger as logger

class FlopocoMissingImplementationError(Exception):
    """Unsynthesizable operator"""

we_min, we_max = 5, 15
wf_min, wf_max = 10, 112
we_range = list(range(we_min, we_max + 1))
wf_range = list(range(wf_min, wf_max + 1))

directory = 'ce/semantics/'
default_file = directory + 'area.pkl'
template_file = directory + 'template.vhdl'

device_name = 'Virtex6'
device_model = 'xc6vlx760'

@contextmanager
def cd(d):
    p = os.path.abspath(os.curdir)
    if d:
        sh.mkdir('-p', d)
        sh.cd(d)
    try:
        yield
    except Exception:
        raise
    finally:
        sh.cd(p)

def get_luts(file_name):
    from bs4 import BeautifulSoup
    with open(file_name, 'r') as f:
        f = BeautifulSoup(f.read())
        app = f.document.application
        util = app.find('section', stringid='XST_DEVICE_UTILIZATION_SUMMARY')
        luts = util.find('item', stringid='XST_NUMBER_OF_SLICE_LUTS')
        return luts.get('value')

def flopoco(op, we, wf, f=None, dir=None):
    from ce.expr import ADD_OP, MULTIPLY_OP
    flopoco_cmd = []
    flopoco_cmd += ['-target=' + device_name]
    dir = dir or tempfile.mktemp(suffix='/')
    with cd(dir):
        if f is None:
            f = tempfile.mktemp(suffix='.vhdl')
        flopoco_cmd += ['-outputfile=%s' % f]
        if op == 'add' or op == ADD_OP:
            flopoco_cmd += ['FPAdder', we, wf]
        elif op == 'mul' or op == MULTIPLY_OP:
            flopoco_cmd += ['FPMultiplier', we, wf, wf]
        else:
            raise ValueError('Unrecognised operator %s' % str(op))
        logger.debug('Flopoco', flopoco_cmd)
        sh.flopoco(*flopoco_cmd)
        try:
            with open(f) as fh:
                if not fh.read():
                    raise IOError()
        except (IOError, FileNotFoundError):
            logger.error('Flopoco failed to generate file %s' % f)
            raise
    return dir, f

def xilinx(f, dir=None):
    file_base = os.path.split(f)[1]
    file_base = os.path.splitext(file_base)[0]
    g = file_base + '.ngc'
    cmd = ['run', '-p', device_model]
    cmd += ['-ifn', f, '-ifmt', 'VHDL']
    cmd += ['-ofn', g, '-ofmt', 'NGC']
    dir = dir or tempfile.mktemp(suffix='/')
    with cd(dir):
        logger.debug('Xilinx', repr(cmd))
        sh.xst(sh.echo(*cmd), _out='out.log', _err='err.log')
        return get_luts(file_base + '.ngc_xst.xrpt')

def eval_operator(op, we, wf, f=None, dir=None):
    dir, f = flopoco(op, we, wf, f, dir)
    return dict(op=op, we=we, wf=wf, value=xilinx(f, dir))

@timeit
def _para_synth(op_we_wf):
    op, we, wf = op_we_wf
    work_dir = 'syn_%d' % os.getpid()
    try:
        item = eval_operator(op, we, wf, f=None, dir=work_dir)
        logger.info('Processed', item)
        return item
    except sh.ErrorReturnCode:
        logger.error('Error processing %s, %d, %d' % op_we_wf)

_pool = None

def pool():
    global _pool
    if _pool is None:
        import multiprocessing
        _pool = multiprocessing.Pool()
    return _pool

@timeit
def batch_synth(we_range, wf_range):
    import itertools
    args = itertools.product(['add', 'mul'], we_range, wf_range)
    return list(pool().imap_unordered(_para_synth, args))

def load(file_name):
    import pickle
    with open(file_name, 'rb') as f:
        return pickle.loads(f.read())

def save(file_name, results):
    import pickle
    results = [i for i in results if not i is None]
    with open(file_name, 'wb') as f:
        pickle.dump(results, f)

def plot(results):
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    fig = plt.figure()
    ax = Axes3D(fig)
    vl = []
    for i in results:
        xv, yv, zv = int(i['we']), int(i['wf']), int(i['value'])
        if zv < 0:
            continue
        vl.append((xv, yv, zv))
    ax.scatter(*zip(*vl))
    plt.show()

if not os.path.isfile(default_file):
    logger.warning('area statistics file does not exist, synthesizing...')
    save(default_file, batch_synth(we_range, wf_range))

_add = {}
_mul = {}
for i in load(default_file):
    xv, yv, zv = int(i['we']), int(i['wf']), int(i['value'])
    if zv <= 0:
        continue
    if i['op'] == 'add':
        _add[xv, yv] = zv
    elif i['op'] == 'mul':
        _mul[xv, yv] = zv

def _impl(_dict, we, wf):
    try:
        return _dict[we, wf]
    except KeyError:
        if not wf in wf_range:
            raise FlopocoMissingImplementationError(
                'Precision %d out of range' % wf)
        elif not we in we_range:
            raise FlopocoMissingImplementationError(
                'Exponent width %d out of range' % we)
        return _impl(_dict, we + 1, wf)

def adder(we, wf):
    return _impl(_add, we, wf)

def multiplier(we, wf):
    return _impl(_mul, we, wf)

@cached
def keys():
    return sorted(list(set(_add.keys()) & set(_mul.keys())))

class CodeGenerator(object):

    def __init__(self, expr, var_env, prec, file_name=None, dir=None):
        from ce.expr import Expr
        self.expr = Expr(expr)
        self.var_env = var_env
        self.wf = prec
        self.we = self.expr.exponent_width(var_env, prec)
        self.dir = dir or tempfile.mktemp(suffix='/')
        with cd(self.dir):
            self.f = file_name or tempfile.mktemp(suffix='.vhdl', dir=dir)

    def generate(self):
        from akpytemp import Template

        ops = set()
        in_ports = set()
        out_port, ls = self.expr.as_labels()
        wires = set()
        signals = set()

        def wire(op, in1, in2, out):
            def wire_name(i):
                if i in signals:
                    return i.signal_name()
                if i in in_ports:
                    return i.port_name()
                if i == out_port:
                    return 'p_out'
            for i in [in1, in2, out]:
                # a variable represented as a string is a port
                if isinstance(i.e, str):
                    in_ports.add(i)
                    continue
                # a number is a port
                try:
                    float(i.e)
                    in_ports.add(i)
                    continue
                except (TypeError, ValueError):
                    pass
                # a range is a port
                try:
                    a, b = i.e
                    float(a), float(b)
                    in_ports.add(i)
                    continue
                except (TypeError, ValueError):
                    pass
                # an expression, need a signal for its output
                try:
                    i.e.op
                    if i != out_port:
                        signals.add(i)
                except AttributeError:
                    pass
            wires.add((op, wire_name(in1), wire_name(in2), wire_name(out)))

        for out, e in ls.items():
            try:
                op, in1, in2 = e.op, e.a1, e.a2
                wire(op, in1, in2, out)
                ops.add(e.op)
            except AttributeError:
                pass
        in_ports = [i.port_name() for i in in_ports]
        out_port = 'p_out'
        signals = [i.signal_name() for i in signals]
        logger.debug(in_ports, signals, wires)
        Template(path=template_file).save(
            path=self.f, directory=self.dir, flopoco=flopoco,
            ops=ops, e=self.expr,
            we=self.we, wf=self.wf,
            in_ports=in_ports, out_port=out_port,
            signals=signals, wires=wires)
        return self.f

def eval_expr(expr, var_env, prec):
    dir = tempfile.mktemp(suffix='/')
    f = CodeGenerator(expr, var_env, prec, dir=dir).generate()
    logger.debug('Synthesising', f)
    return xilinx(f, dir=dir)

if __name__ == '__main__':
    from ce.expr import Expr
    logger.set_context(level=logger.levels.info)
    p = 23
    e = Expr('a + b + c')
    v = {'a': ['0', '1'], 'b': ['0', '100'], 'c': ['0', '100000']}
    logger.info(e.area(v, p).area)
    logger.info(e.real_area(v, p))
    plot(load(default_file))
<|endoftext|>