<commit_before>import unittest
import mock
from ...management.organizations import Organizations

class TestOrganizations(unittest.TestCase):

    def test_init_with_optionals(self):
        t = Organizations(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
        self.assertEqual(t.client.timeout, (10, 2))
        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
        self.assertEqual(telemetry_header, None)

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_all_organizations(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')

        # Default parameters are requested
        c.all_organizations()

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'page': None,
                                            'per_page': None})

        # Specific pagination
        c.all_organizations(page=7, per_page=25)

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'page': 7,
                                            'per_page': 25})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_get_organization_by_name(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.get_organization_by_name('test-org')

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'name': 'test-org'})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_create_organization(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.create_organization({'a': 'b', 'c': 'd'})

        mock_instance.post.assert_called_with(
            'https://domain/api/v2/organizations',
            data={'a': 'b', 'c': 'd'}
        )

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_update(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.update('this-id', {'a': 'b', 'c': 'd'})

        args, kwargs = mock_instance.patch.call_args

        self.assertEqual('https://domain/api/v2/organizations/this-id', args[0])
        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_delete_organization(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.delete_organization('this-id')

        mock_instance.delete.assert_called_with(
            'https://domain/api/v2/organizations/this-id'
        )<commit_msg>fix wrong method call<commit_after>import unittest
import mock
from ...management.organizations import Organizations

class TestOrganizations(unittest.TestCase):

    def test_init_with_optionals(self):
        t = Organizations(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
        self.assertEqual(t.client.timeout, (10, 2))
        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
        self.assertEqual(telemetry_header, None)

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_all_organizations(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')

        # Default parameters are requested
        c.all_organizations()

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'page': None,
                                            'per_page': None})

        # Specific pagination
        c.all_organizations(page=7, per_page=25)

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'page': 7,
                                            'per_page': 25})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_get_organization_by_name(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.get_organization_by_name('test-org')

        args, kwargs = mock_instance.get.call_args

        self.assertEqual('https://domain/api/v2/organizations', args[0])
        self.assertEqual(kwargs['params'], {'name': 'test-org'})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_create_organization(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.create_organization({'a': 'b', 'c': 'd'})

        mock_instance.post.assert_called_with(
            'https://domain/api/v2/organizations',
            data={'a': 'b', 'c': 'd'}
        )

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_update_organization(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.update_organization('this-id', {'a': 'b', 'c': 'd'})

        args, kwargs = mock_instance.patch.call_args

        self.assertEqual('https://domain/api/v2/organizations/this-id', args[0])
        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})

    @mock.patch('auth0.v3.management.organizations.RestClient')
    def test_delete_organization(self, mock_rc):
        mock_instance = mock_rc.return_value

        c = Organizations(domain='domain', token='jwttoken')
        c.delete_organization('this-id')

        mock_instance.delete.assert_called_with(
            'https://domain/api/v2/organizations/this-id'
        )<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: ISO-8859-15 -*-
# =============================================================================
# Copyright (c) 2009 Tom Kralidis
#
# Authors : Tom Kralidis <tomkralidis@hotmail.com>
#
# Contact email: tomkralidis@hotmail.com
# =============================================================================

""" ISO metadata parser """

import StringIO
from owslib.etree import etree
from owslib import util

# default variables

namespaces = {
    None : 'http://www.isotc211.org/2005/gmd',
    'gco': 'http://www.isotc211.org/2005/gco',
    'gmd': 'http://www.isotc211.org/2005/gmd',
    'gts': 'http://www.isotc211.org/2005/gts',
    'srv': 'http://www.isotc211.org/2005/srv',
    'xlink': 'http://www.w3.org/1999/xlink'
}

class MD_Metadata(object):
    """ Process gmd:MD_Metadata """
    def __init__(self, md, identifier=None):
        if identifier is None:
            val = md.find(util.nspath('fileIdentifier', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
            self.identifier = util.testXMLValue(val)
        else:
            self.identifier = identifier

        val = md.find(util.nspath('language', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.language = util.testXMLValue(val)

        self.charset = _testCodeListValue(md.find(util.nspath('characterSet/MD_CharacterSetCode', namespaces['gmd'])))

        self.hierarchy = _testCodeListValue(md.find(util.nspath('hierarchyLevel/MD_ScopeCode', namespaces['gmd'])))

        val = md.find(util.nspath('contact/CI_ResponsibleParty', namespaces['gmd']))
        if val is not None:
            self.contact = CI_ResponsibleParty(val)
        else:
            self.contact = None

        val = md.find(util.nspath('dateStamp', namespaces['gmd']) + '/' + util.nspath('DateTime', namespaces['gco']))
        self.datestamp = util.testXMLValue(val)

        val = md.find(util.nspath('metadataStandardName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.stdname = util.testXMLValue(val)

        val = md.find(util.nspath('metadataStandardVersion', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.stdver = util.testXMLValue(val)

        val = md.find(util.nspath('referenceSystemInfo/MD_ReferenceSystem', namespaces['gmd']))
        if val is not None:
            self.referencesystem = MD_ReferenceSystem(val)
        else:
            self.referencesystem = None

        val = md.find(util.nspath('identificationInfo/MD_DataIdentification', namespaces['gmd']))
        val2 = md.find(util.nspath('identificationInfo', namespaces['gmd']) + '/' + util.nspath('SV_ServiceIdentification', namespaces['srv']))

        if val is not None:
            self.identification = MD_DataIdentification(val, 'dataset')
        elif val2 is not None:
            self.identification = MD_DataIdentification(val2, 'service')
            self.identification.service = SV_ServiceIdentification(val2)
        else:
            self.identification = None

        val = md.find(util.nspath('distributionInfo/MD_Distribution', namespaces['gmd']))
        if val is not None:
            self.distribution = MD_Distribution(val)
        else:
            self.distribution = None

class CI_ResponsibleParty(object):
    """ process CI_ResponsibleParty """
    def __init__(self, md):
        val = md.find(util.nspath('individualName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.name = util.testXMLValue(val)

        val = md.find(util.nspath('organisationName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.organization = util.testXMLValue(val)

        val = md.find(util.nspath('positionName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.position = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/phone/CI_Telephone/voice', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.phone = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/phone/CI_Telephone/facsimile', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.fax = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/deliveryPoint', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.address = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/city', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.city = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/administrativeArea', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.region = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/postalCode', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.postcode = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/country', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.country = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/onlineResource/CI_OnlineResource', namespaces['gmd']))
        if val is not None:
          self.onlineresource = CI_OnlineResource(val)
        else:
          self.onlineresource = None

        self.role = _testCodeListValue(md.find(util.nspath('role/CI_RoleCode', namespaces['gmd'])))

class MD_DataIdentification(object):
    """ process MD_DataIdentification """
    def __init__(self, md, identtype):
        self.identtype = identtype
        val = md.find(util.nspath('citation/CI_Citation/title', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.title = util.testXMLValue(val)

        val = md.find(util.nspath('citation/CI_Citation/date/CI_Date/date', namespaces['gmd']) + '/' + util.nspath('DateTime', namespaces['gco']))
        self.date = util.testXMLValue(val)

        self.datetype = _testCodeListValue(md.find(util.nspath('citation/CI_Citation/date/CI_Date/dateType/CI_DateTypeCode', namespaces['gmd'])))

        val = md.find(util.nspath('abstract', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.abstract = util.testXMLValue(val)

        val = md.find(util.nspath('purpose', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.purpose = util.testXMLValue(val, True)

        self.status = _testCodeListValue(md.find(util.nspath('status/MD_ProgressCode', namespaces['gmd'])))

        val = md.find(util.nspath('pointOfContact/CI_ResponsibleParty', namespaces['gmd']))

        if val is not None:
            self.contact = CI_ResponsibleParty(val)
        else:
            self.contact = None

        self.keywords = {}

        self.keywords['type'] = _testCodeListValue(md.find(util.nspath('descriptiveKeywords/MD_Keywords/type/MD_KeywordTypeCode', namespaces['gmd'])))

        self.keywords['list'] = []
        for i in md.findall(util.nspath('descriptiveKeywords/MD_Keywords/keyword', namespaces['gmd'])):
            k = i.find(util.nspath('CharacterString', namespaces['gco']))
            self.keywords['list'].append(util.testXMLValue(k))

        val = md.find(util.nspath('topicCategory/MD_TopicCategoryCode', namespaces['gmd']))
        self.topiccategory = util.testXMLValue(val)

        val = md.find(util.nspath('extent/EX_Extent', namespaces['gmd']))

        if val is not None:
            self.bbox = EX_Extent(val)
        else:
            self.bbox = None

class MD_Distribution(object):
    """ process MD_Distribution """
    def __init__(self, md):
        val = md.find(util.nspath('distributionFormat/MD_Format/name', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.format = util.testXMLValue(val)

        val = md.find(util.nspath('distributionFormat/MD_Format/version', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.version = util.testXMLValue(val)

        val = md.find(util.nspath('transferOptions/MD_DigitalTransferOptions/onLine/CI_OnlineResource', namespaces['gmd']))

        if val is not None:
            self.onlineresource = CI_OnlineResource(val)
        else:
            self.onlineresource = None

class SV_ServiceIdentification(object):
    """ process SV_ServiceIdentification """
    def __init__(self, md):
        val = md.find(util.nspath('serviceType', namespaces['srv']) + '/' + util.nspath('LocalName', namespaces['gco']))
        self.type = util.testXMLValue(val)

        val = md.find(util.nspath('serviceTypeVersion', namespaces['srv']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.version = util.testXMLValue(val)

        val = md.find(util.nspath('accessProperties', namespaces['srv']) + '/' + util.nspath('MD_StandardOrderProcess/fees', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.fees = util.testXMLValue(val)

        val = md.find(util.nspath('extent', namespaces['srv']) + '/' + util.nspath('EX_Extent', namespaces['gmd']))

        if val is not None:
            self.bbox = EX_Extent(val)
        else:
            self.bbox = None

        self.couplingtype = _testCodeListValue(md.find(util.nspath('couplingType/SV_CouplingType', namespaces['gmd'])))

        self.operations = []

        for i in md.findall(util.nspath('containsOperations', namespaces['srv'])):
            tmp = {}
            val = i.find(util.nspath('SV_OperationMetadata/operationName', namespaces['srv']) + '/' + util.nspath('CharacterString', namespaces['gco']))
            tmp['name'] = util.testXMLValue(val)
            tmp['dcplist'] = []
            for d in i.findall(util.nspath('SV_OperationMetadata/DCP', namespaces['srv'])):
                tmp2 = _testCodeListValue(d.find(util.nspath('DCPList', namespaces['srv'])))
                tmp['dcplist'].append(tmp2)

            tmp['connectpoint'] = []

            for d in i.findall(util.nspath('SV_OperationMetadata/connectPoint', namespaces['srv'])):
                tmp3 = d.find(util.nspath('CI_OnlineResource', namespaces['gmd']))
                tmp['connectpoint'].append(CI_OnlineResource(tmp3))
            self.operations.append(tmp)

        self.operateson = []

        for i in md.findall(util.nspath('operatesOn', namespaces['srv'])):
            tmp = {}
            tmp['uuidref'] = i.attrib.get('uuidref')
            tmp['href'] = i.attrib.get(util.nspath('href', namespaces['xlink']))
            tmp['title'] = i.attrib.get(util.nspath('title', namespaces['xlink']))
            self.operateson.append(tmp)

class CI_OnlineResource(object):
    """ process CI_OnlineResource """
    def __init__(self,md):
        val = md.find(util.nspath('linkage/URL', namespaces['gmd']))
        self.url = util.testXMLValue(val)

        val = md.find(util.nspath('protocol', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.protocol = util.testXMLValue(val)

        val = md.find(util.nspath('name', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.name = util.testXMLValue(val)

        val = md.find(util.nspath('description', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.description = util.testXMLValue(val)

        self.function = _testCodeListValue(md.find(util.nspath('function/CI_OnLineFunctionCode', namespaces['gmd'])))

class EX_Extent(object):
    """ process EX_Extent """
    def __init__(self, md):
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/westBoundLongitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.minx = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/eastBoundLongitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.maxx = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/southBoundLatitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.miny = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/northBoundLatitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.maxy = util.testXMLValue(val)

class MD_ReferenceSystem(object):
    """ process MD_ReferenceSystem """
    def __init__(self, md):
        val = md.find(util.nspath('referenceSystemIdentifier/RS_Identifier/code', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.code = util.testXMLValue(val)

def _testCodeListValue(elpath):
    if elpath is not None:
        return util.testXMLValue(elpath.attrib.get('codeListValue'), True)
    else:
        return None
<commit_msg>remove StringIO (not needed)<commit_after>#!/usr/bin/python
# -*- coding: ISO-8859-15 -*-
# =============================================================================
# Copyright (c) 2009 Tom Kralidis
#
# Authors : Tom Kralidis <tomkralidis@hotmail.com>
#
# Contact email: tomkralidis@hotmail.com
# =============================================================================

""" ISO metadata parser """

from owslib.etree import etree
from owslib import util

# default variables

namespaces = {
    None : 'http://www.isotc211.org/2005/gmd',
    'gco': 'http://www.isotc211.org/2005/gco',
    'gmd': 'http://www.isotc211.org/2005/gmd',
    'gts': 'http://www.isotc211.org/2005/gts',
    'srv': 'http://www.isotc211.org/2005/srv',
    'xlink': 'http://www.w3.org/1999/xlink'
}

class MD_Metadata(object):
    """ Process gmd:MD_Metadata """
    def __init__(self, md, identifier=None):
        if identifier is None:
            val = md.find(util.nspath('fileIdentifier', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
            self.identifier = util.testXMLValue(val)
        else:
            self.identifier = identifier

        val = md.find(util.nspath('language', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.language = util.testXMLValue(val)

        self.charset = _testCodeListValue(md.find(util.nspath('characterSet/MD_CharacterSetCode', namespaces['gmd'])))

        self.hierarchy = _testCodeListValue(md.find(util.nspath('hierarchyLevel/MD_ScopeCode', namespaces['gmd'])))

        val = md.find(util.nspath('contact/CI_ResponsibleParty', namespaces['gmd']))
        if val is not None:
            self.contact = CI_ResponsibleParty(val)
        else:
            self.contact = None

        val = md.find(util.nspath('dateStamp', namespaces['gmd']) + '/' + util.nspath('DateTime', namespaces['gco']))
        self.datestamp = util.testXMLValue(val)

        val = md.find(util.nspath('metadataStandardName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.stdname = util.testXMLValue(val)

        val = md.find(util.nspath('metadataStandardVersion', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.stdver = util.testXMLValue(val)

        val = md.find(util.nspath('referenceSystemInfo/MD_ReferenceSystem', namespaces['gmd']))
        if val is not None:
            self.referencesystem = MD_ReferenceSystem(val)
        else:
            self.referencesystem = None

        val = md.find(util.nspath('identificationInfo/MD_DataIdentification', namespaces['gmd']))
        val2 = md.find(util.nspath('identificationInfo', namespaces['gmd']) + '/' + util.nspath('SV_ServiceIdentification', namespaces['srv']))

        if val is not None:
            self.identification = MD_DataIdentification(val, 'dataset')
        elif val2 is not None:
            self.identification = MD_DataIdentification(val2, 'service')
            self.identification.service = SV_ServiceIdentification(val2)
        else:
            self.identification = None

        val = md.find(util.nspath('distributionInfo/MD_Distribution', namespaces['gmd']))
        if val is not None:
            self.distribution = MD_Distribution(val)
        else:
            self.distribution = None

class CI_ResponsibleParty(object):
    """ process CI_ResponsibleParty """
    def __init__(self, md):
        val = md.find(util.nspath('individualName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.name = util.testXMLValue(val)

        val = md.find(util.nspath('organisationName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.organization = util.testXMLValue(val)

        val = md.find(util.nspath('positionName', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.position = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/phone/CI_Telephone/voice', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.phone = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/phone/CI_Telephone/facsimile', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.fax = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/deliveryPoint', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.address = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/city', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.city = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/administrativeArea', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.region = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/postalCode', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.postcode = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/address/CI_Address/country', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.country = util.testXMLValue(val)

        val = md.find(util.nspath('contactInfo/CI_Contact/onlineResource/CI_OnlineResource', namespaces['gmd']))
        if val is not None:
          self.onlineresource = CI_OnlineResource(val)
        else:
          self.onlineresource = None

        self.role = _testCodeListValue(md.find(util.nspath('role/CI_RoleCode', namespaces['gmd'])))

class MD_DataIdentification(object):
    """ process MD_DataIdentification """
    def __init__(self, md, identtype):
        self.identtype = identtype
        val = md.find(util.nspath('citation/CI_Citation/title', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.title = util.testXMLValue(val)

        val = md.find(util.nspath('citation/CI_Citation/date/CI_Date/date', namespaces['gmd']) + '/' + util.nspath('DateTime', namespaces['gco']))
        self.date = util.testXMLValue(val)

        self.datetype = _testCodeListValue(md.find(util.nspath('citation/CI_Citation/date/CI_Date/dateType/CI_DateTypeCode', namespaces['gmd'])))

        val = md.find(util.nspath('abstract', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.abstract = util.testXMLValue(val)

        val = md.find(util.nspath('purpose', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.purpose = util.testXMLValue(val, True)

        self.status = _testCodeListValue(md.find(util.nspath('status/MD_ProgressCode', namespaces['gmd'])))

        val = md.find(util.nspath('pointOfContact/CI_ResponsibleParty', namespaces['gmd']))

        if val is not None:
            self.contact = CI_ResponsibleParty(val)
        else:
            self.contact = None

        self.keywords = {}

        self.keywords['type'] = _testCodeListValue(md.find(util.nspath('descriptiveKeywords/MD_Keywords/type/MD_KeywordTypeCode', namespaces['gmd'])))

        self.keywords['list'] = []
        for i in md.findall(util.nspath('descriptiveKeywords/MD_Keywords/keyword', namespaces['gmd'])):
            k = i.find(util.nspath('CharacterString', namespaces['gco']))
            self.keywords['list'].append(util.testXMLValue(k))

        val = md.find(util.nspath('topicCategory/MD_TopicCategoryCode', namespaces['gmd']))
        self.topiccategory = util.testXMLValue(val)

        val = md.find(util.nspath('extent/EX_Extent', namespaces['gmd']))

        if val is not None:
            self.bbox = EX_Extent(val)
        else:
            self.bbox = None

class MD_Distribution(object):
    """ process MD_Distribution """
    def __init__(self, md):
        val = md.find(util.nspath('distributionFormat/MD_Format/name', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.format = util.testXMLValue(val)

        val = md.find(util.nspath('distributionFormat/MD_Format/version', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.version = util.testXMLValue(val)

        val = md.find(util.nspath('transferOptions/MD_DigitalTransferOptions/onLine/CI_OnlineResource', namespaces['gmd']))

        if val is not None:
            self.onlineresource = CI_OnlineResource(val)
        else:
            self.onlineresource = None

class SV_ServiceIdentification(object):
    """ process SV_ServiceIdentification """
    def __init__(self, md):
        val = md.find(util.nspath('serviceType', namespaces['srv']) + '/' + util.nspath('LocalName', namespaces['gco']))
        self.type = util.testXMLValue(val)

        val = md.find(util.nspath('serviceTypeVersion', namespaces['srv']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.version = util.testXMLValue(val)

        val = md.find(util.nspath('accessProperties', namespaces['srv']) + '/' + util.nspath('MD_StandardOrderProcess/fees', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.fees = util.testXMLValue(val)

        val = md.find(util.nspath('extent', namespaces['srv']) + '/' + util.nspath('EX_Extent', namespaces['gmd']))

        if val is not None:
            self.bbox = EX_Extent(val)
        else:
            self.bbox = None

        self.couplingtype = _testCodeListValue(md.find(util.nspath('couplingType/SV_CouplingType', namespaces['gmd'])))

        self.operations = []

        for i in md.findall(util.nspath('containsOperations', namespaces['srv'])):
            tmp = {}
            val = i.find(util.nspath('SV_OperationMetadata/operationName', namespaces['srv']) + '/' + util.nspath('CharacterString', namespaces['gco']))
            tmp['name'] = util.testXMLValue(val)
            tmp['dcplist'] = []
            for d in i.findall(util.nspath('SV_OperationMetadata/DCP', namespaces['srv'])):
                tmp2 = _testCodeListValue(d.find(util.nspath('DCPList', namespaces['srv'])))
                tmp['dcplist'].append(tmp2)

            tmp['connectpoint'] = []

            for d in i.findall(util.nspath('SV_OperationMetadata/connectPoint', namespaces['srv'])):
                tmp3 = d.find(util.nspath('CI_OnlineResource', namespaces['gmd']))
                tmp['connectpoint'].append(CI_OnlineResource(tmp3))
            self.operations.append(tmp)

        self.operateson = []

        for i in md.findall(util.nspath('operatesOn', namespaces['srv'])):
            tmp = {}
            tmp['uuidref'] = i.attrib.get('uuidref')
            tmp['href'] = i.attrib.get(util.nspath('href', namespaces['xlink']))
            tmp['title'] = i.attrib.get(util.nspath('title', namespaces['xlink']))
            self.operateson.append(tmp)

class CI_OnlineResource(object):
    """ process CI_OnlineResource """
    def __init__(self,md):
        val = md.find(util.nspath('linkage/URL', namespaces['gmd']))
        self.url = util.testXMLValue(val)

        val = md.find(util.nspath('protocol', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.protocol = util.testXMLValue(val)

        val = md.find(util.nspath('name', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.name = util.testXMLValue(val)

        val = md.find(util.nspath('description', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.description = util.testXMLValue(val)

        self.function = _testCodeListValue(md.find(util.nspath('function/CI_OnLineFunctionCode', namespaces['gmd'])))

class EX_Extent(object):
    """ process EX_Extent """
    def __init__(self, md):
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/westBoundLongitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.minx = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/eastBoundLongitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.maxx = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/southBoundLatitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.miny = util.testXMLValue(val)
        val = md.find(util.nspath('geographicElement/EX_GeographicBoundingBox/northBoundLatitude', namespaces['gmd']) + '/' + util.nspath('Decimal', namespaces['gco']))
        self.maxy = util.testXMLValue(val)

class MD_ReferenceSystem(object):
    """ process MD_ReferenceSystem """
    def __init__(self, md):
        val = md.find(util.nspath('referenceSystemIdentifier/RS_Identifier/code', namespaces['gmd']) + '/' + util.nspath('CharacterString', namespaces['gco']))
        self.code = util.testXMLValue(val)

def _testCodeListValue(elpath):
    if elpath is not None:
        return util.testXMLValue(elpath.attrib.get('codeListValue'), True)
    else:
        return None
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import gc
import riak

from bottle import Bottle, abort, request
from bottle.ext.websocket import websocket
from bottle.ext.mongo import MongoPlugin

from pandas import DataFrame

from utils import df_generate, conf

stream_app = Bottle()
mongo = MongoPlugin(
    uri=conf("mongodb")["uri"],
    db=conf("mongodb")["db"],
    json_mongo=True)
stream_app.install(mongo)

@stream_app.route('/data/<slug>', apply=[websocket])
def data(ws, mongodb, slug):

    if not ws:
        abort(400, 'Expected WebSocket request.')

    MyClient = riak.RiakClient(protocol=conf("riak")["protocol"],
                               http_port=conf("riak")["http_port"],
                               host=conf("riak")["host"])

    MyBucket = MyClient.bucket(conf("riak")["bucket"])

    element = mongodb['element'].find_one({'slug': slug})
    element['page_limit'] = 50

    columns = json.loads(MyBucket.get(
        '{}-columns'.format(element.get('cube'))).data or [])

    fields = columns
    if request.GET.get('fields', None):
        fields = request.GET.get('fields').split(',')

    cube_last_update = mongodb['cube'].find_one({'slug': element.get('cube')})
    ws.send(json.dumps({'type': 'last_update',
                        'data': str(cube_last_update.get('lastupdate', ''))}))

    ws.send(json.dumps({'type': 'columns', 'data': fields}))

    filters = [i[0] for i in request.GET.iteritems()
               if len(i[0].split('filter__')) > 1]

    if element['type'] == 'grid':
        page = int(request.GET.get('page', 1))
        page_start = 0
        page_end = element['page_limit']
        if page >= 2:
            page_end = element['page_limit'] * page
            page_start = page_end - element['page_limit']
    else:
        page_start = None
        page_end = None

    df = DataFrame(MyBucket.get(element.get('cube')).data, columns=fields)
    if len(filters) >= 1:
        for f in filters:
            df = df.query(df_generate(df, request.GET.get(f), f))

    groupby = []
    if request.GET.get('groupby', None):
        groupby = request.GET.get('groupby', ).split(',')
    if len(groupby) >= 1:
        df = df.groupby(groupby)

    if request.GET.get('orderby', element.get('orderby', None)):
        orderby = request.GET.get('orderby', element.get('orderby', ''))
        if type(orderby) == str:
            orderby = orderby.split(',')
        orderby__order = request.GET.get('orderby__order',
                                         element.get('orderby__order', ''))
        if type(orderby__order) == str:
            orderby__order = orderby__order.split(',')
        ind = 0
        for orde in orderby__order:
            if orde == '0':
                orderby__order[ind] = False
            else:
                orderby__order[ind] = True
            ind += 1
        df = df.sort(orderby, ascending=orderby__order)

    ws.send(json.dumps({'type': 'max_page', 'data': len(df)}))

    # CLEAN MEMORY
    del filters, fields, columns
    gc.collect()
    categories = []
    for i in df.to_dict(outtype='records')[page_start:page_end]:
        if element.get('categories', None):
            categories.append(i[element.get('categories')])
        ws.send(json.dumps({'type': 'data', 'data': i}))

    # CLEAN MEMORY
    del df
    gc.collect()

    ws.send(json.dumps({'type': 'categories', 'data': categories}))
    ws.send(json.dumps({'type': 'close'}))

    # CLEAN MEMORY
    del categories
    gc.collect()
<commit_msg>used DataFrame Search Column on data stream<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import gc
import riak

from bottle import Bottle, abort, request
from bottle.ext.websocket import websocket
from bottle.ext.mongo import MongoPlugin

from pandas import DataFrame

from utils import df_generate, conf, DataFrameSearchColumn

stream_app = Bottle()
mongo = MongoPlugin(
    uri=conf("mongodb")["uri"],
    db=conf("mongodb")["db"],
    json_mongo=True)
stream_app.install(mongo)

@stream_app.route('/data/<slug>', apply=[websocket])
def data(ws, mongodb, slug):

    if not ws:
        abort(400, 'Expected WebSocket request.')

    MyClient = riak.RiakClient(protocol=conf("riak")["protocol"],
                               http_port=conf("riak")["http_port"],
                               host=conf("riak")["host"])

    MyBucket = MyClient.bucket(conf("riak")["bucket"])

    element = mongodb['element'].find_one({'slug': slug})
    element['page_limit'] = 50

    columns = json.loads(MyBucket.get(
        '{}-columns'.format(element.get('cube'))).data or [])

    fields = columns
    if request.GET.get('fields', None):
        fields = request.GET.get('fields').split(',')

    cube_last_update = mongodb['cube'].find_one({'slug': element.get('cube')})
    ws.send(json.dumps({'type': 'last_update',
                        'data': str(cube_last_update.get('lastupdate', ''))}))

    ws.send(json.dumps({'type': 'columns', 'data': fields}))

    filters = [i[0] for i in request.GET.iteritems()
               if len(i[0].split('filter__')) > 1]

    if element['type'] == 'grid':
        page = int(request.GET.get('page', 1))
        page_start = 0
        page_end = element['page_limit']
        if page >= 2:
            page_end = element['page_limit'] * page
            page_start = page_end - element['page_limit']
    else:
        page_start = None
        page_end = None

    df = DataFrame(MyBucket.get(element.get('cube')).data, columns=fields)
    if len(filters) >= 1:
        for f in filters:
            s = f.split('__')
            field = s[1]
            operator = s[2]
            value = request.GET.get(f)
            if operator == 'like':
                df = DataFrameSearchColumn(df, field, value)
            else:
                df = df.query(df_generate(df, value, f))

    groupby = []
    if request.GET.get('groupby', None):
        groupby = request.GET.get('groupby', ).split(',')
    if len(groupby) >= 1:
        df = df.groupby(groupby)

    if request.GET.get('orderby', element.get('orderby', None)):
        orderby = request.GET.get('orderby', element.get('orderby', ''))
        if type(orderby) == str:
            orderby = orderby.split(',')
        orderby__order = request.GET.get('orderby__order',
                                         element.get('orderby__order', ''))
        if type(orderby__order) == str:
            orderby__order = orderby__order.split(',')
        ind = 0
        for orde in orderby__order:
            if orde == '0':
                orderby__order[ind] = False
            else:
                orderby__order[ind] = True
            ind += 1
        df = df.sort(orderby, ascending=orderby__order)

    ws.send(json.dumps({'type': 'max_page', 'data': len(df)}))

    # CLEAN MEMORY
    del filters, fields, columns
    gc.collect()
    categories = []
    for i in df.to_dict(outtype='records')[page_start:page_end]:
        if element.get('categories', None):
            categories.append(i[element.get('categories')])
        ws.send(json.dumps({'type': 'data', 'data': i}))

    # CLEAN MEMORY
    del df
    gc.collect()

    ws.send(json.dumps({'type': 'categories', 'data': categories}))
    ws.send(json.dumps({'type': 'close'}))

    # CLEAN MEMORY
    del categories
    gc.collect()
<|endoftext|>


<commit_before>"""
Defines the concrete top-level Enable 'Window' class for the Pyglet framework.
Uses the Kiva GL backend.
"""

import sys
import warnings

# Pyglet imports
import pyglet
from pyglet import window
from pyglet.window import key

# Enthought library imports
from enthought.traits.api import Any, Float, Instance, Trait

# Enable imports
from enthought.enable2.base import send_event_to, union_bounds
from enthought.enable2.component  import Component
from enthought.enable2.events import MouseEvent, KeyEvent, DragEvent
from enthought.enable2.graphics_context import GraphicsContextEnable
from enthought.enable2.abstract_window import AbstractWindow

# local, relative imports
from constants import BUTTON_NAME_MAP, KEY_MAP, POINTER_MAP

class PygletMouseEvent(object):
    """ Because Pyglet doesn't have a native mouse event object, we use
    this to encapsulate all the possible state when we receive any mouse-
    related event.
    """
    def __init__(self, x, y, dx=0, dy=0, buttons=None, modifiers=None,
                 scroll_x=0, scroll_y=0):
        """ **buttons** is a list of buttons """
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.modifiers = modifiers
        self.buttons = buttons
        self.scroll_x = scroll_x
        self.scroll_y = scroll_y

        if modifiers is not None:
            self.shift_pressed = (modifiers & key.MOD_SHIFT)
            self.ctrl_pressed = (modifiers & key.MOD_CTRL)
            self.alt_pressed = (modifiers & key.MOD_ALT)
        else:
            self.shift_pressed = self.ctrl_pressed = self.alt_pressed = False
        return

class PygletWindow(window.Window):
    """ Pyglet recommends subclassing their base Window class as the preferred
    method for customizing behavior.  This PygletWindow class serves to bridge
    events and methods between the Enable layer and Pyglet.

    """

    def __init__(self, enable_window, **kwargs):
        """ PygletWindow needs a reference to the Enable window; other
        arguments are passed through directly to the pyglet.Window constructor.
        """
        self.enable_window = enable_window

        # Whether or not the Enable component stack has requested a redraw
        self._redraw_requested = False

        super(PygletWindow, self).__init__(**kwargs)

        # use a KeyStateHandler to remember the keyboard state.  This
        # is useful since Pyglet separates the notion of keyboard state
        # and character events, and we need to access keyboard state
        # from the on_text handler method.
        self.key_state = key.KeyStateHandler()
        self.push_handlers(self.key_state)

    #-------------------------------------------------------------------------
    # Public methods
    # These are not inherited from/part of the pyglet.window.Window interface
    #-------------------------------------------------------------------------

    def draw(self):
        "Called by the mainloop to perform the actual draw"
        self.enable_window._paint()

    def request_redraw(self, coordinates=None):
        """ Called by **self.enable_window** to request a redraw
        **coordinates** is a tuple (x,y,w,h) of a specific sub-region to
        redraw.
        """
        # TODO: Support the **coordinates** argument
        self._redraw_requested = True

    #-------------------------------------------------------------------------
    # Key/text handling
    #-------------------------------------------------------------------------

    def on_key_press(self, symbol, modifiers):
        return self._on_key_updown(symbol, modifiers, down=False)

    def on_key_release(self, symbol, modifiers):
        return self._on_key_updown(symbol, modifiers)

    def _on_key_updown(self, symbol, modifiers, down=True):
        event = PygletMouseEvent(0, 0, modifiers=modifiers)
        enable_win = self.enable_window
        enable_win.shift_pressed = bool(down & event.shift_pressed)
        enable_win.ctrl_pressed = bool(down & event.ctrl_pressed)
        enable_win.alt_pressed = bool(down & event.alt_pressed)
        # It's important to return False so that the KeyStateHandler
        # can also get this event.
        return False

    def on_text(self, text):
        if self.enable_window.focus_owner is None:
            focus_owner = self.enable_window.component
        else:
            focus_owner = self.enable_window.focus_owner

        if focus_owner is None:
            return

        keys = self.key_state
        enable_event = KeyEvent(character = key,
                          alt_down = keys[key.LALT] | keys[key.RALT],
                          control_down = keys[key.LCTRL] | keys[key.RCTRL],
                          shift_down = keys[key.LSHIFT] | keys[key.RSHIFT],
                          x = self._mouse_x,
                          y = self._mouse_y,
                          window = self.enable_window)
        focus_owner.dispatch(enable_event, "key_pressed")
        return True

    def on_text_motion(self, motion):
        # TODO: See notes.
        pass

    def on_text_motion_select(self, motion):
        # TODO: See notes.
        pass

    #-------------------------------------------------------------------------
    # Mouse handling
    #-------------------------------------------------------------------------

    def on_mouse_motion(self, x, y, dx, dy):
        event = PygletMouseEvent(x, y, dx, dy)
        self.enable_window._handle_mouse_event("mouse_move", event, set_focus=False)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        # TODO: Determine the difference between this and on_mouse_motion;
        # confirm that the correct buttons in **buttons** are down.
        event = PygletMouseEvent(x, y, dx, dy, buttons, modifiers)
        self.enable_window._handle_mouse_event("mouse_move", event, set_focus=False)

    def on_mouse_press(self, x, y, button, modifiers):
        return self._on_mouse_updown(x, y, button, modifiers, "up")

    def on_mouse_release(self, x, y, button, modifiers):
        return self._on_mouse_updown(x, y, button, modifiers, "down")

    def _on_mouse_updown(self, x, y, button, modifiers, which="down"):
        event = PygletMouseEvent(x, y, [button], modifiers)
        mouse = pyglet.window.mouse
        if button == mouse.LEFT:
            name = "left"
        elif button == mouse.MIDDLE:
            name = "middle"
        elif button == mouse.RIGHT:
            name = "right"
        self.enable_window._handle_mouse_event(name+"_"+which, event, set_focus=False)
        # TODO: Confirm that we should consume mouse press/release events
        return True

    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        # TODO: Handle scroll_x
        event = PygletMouseEvent(x, y, scroll_x=scroll_x, scroll_y=scroll_y)
        self.enable_window._handle_mouse_event("mouse_wheel", event, set_focus=False)

    def on_mouse_enter(self, x, y):
        event = PygletMouseEvent(x, y)
        self.enable_window._handle_mouse_event("mouse_enter", event, set_focus=False)

    def on_mouse_leave(self, x, y):
        event = PygletMouseEvent(x, y)
        self.enable_window._handle_mouse_event("mouse_leave", event, set_focus=False)

    #-------------------------------------------------------------------------
    # Window
    #-------------------------------------------------------------------------

    def on_resize(self, width, height):
        self.enable_window.resized = (width, height)
        component = self.enable_window.component
        if hasattr(component, "fit_window") and component.fit_window:
            component.outer_position = [0,0]
            component.outer_bounds = [width, height]
        elif hasattr(component, "resizable"):
            if "h" in component.resizable:
                component.outer_x = 0
                component.outer_width = width
            if "v" in component.resizable:
                component.outer_y = 0
                component.outer_height = height
        return

    def on_close(self):
        pass

    def on_expose(self):
        pass

    def on_move(self, x, y):
        """The window was moved.  x is the distance from the left edge of the
        screen to the left edge of the window.  y is the distance from the top
        edge of the screen to the top edge of the window.
        """
        pass

    def on_activate(self):
        """ The window was activated. """
        pass

    def on_deactivate(self):
        """ The window lost focus. """
        pass

    def on_show(self):
        """ The window was shown. """
        pass

    def on_hide(self):
        """ The window was minimized or hidden. """
        pass

    #-------------------------------------------------------------------------
    # GL context stuff - see the pyglet.window.Window documentation on these
    # methods
    #-------------------------------------------------------------------------

    def on_context_lost(self):
        pass

    def on_context_state_lost(self):
        pass

class Window(AbstractWindow):

    _cursor_color = Any  # PZW: figure out the correct type for this...

    # This is set by downstream components to notify us of whether or not
    # the current drag operation should return DragCopy, DragMove, or DragNone.
    _drag_result = Any

    def __init__(self, parent=None, id=-1, **traits ):
        """ **parent** is an unneeded argument with the pyface backend, but
        we need to preserve compatibility with other AbstractWindow
        subclasses.
        """
        # TODO: Fix fact that other backends' Window classes use positional
        # arguments

        self.control = None
        AbstractWindow.__init__(self, **traits)
        self._mouse_captured = False

        # Due to wx wonkiness, we don't reliably get cursor position from
        # a wx KeyEvent.  Thus, we manually keep track of when we last saw
        # the mouse and use that information instead.  These coordinates are
        # in the wx coordinate space, i.e. pre-self._flip_y().
        self._last_mouse_pos = (0, 0)

        # Create the underlying control.
        self.control = PygletWindow(enable_window=self)

        return

    def _flip_y(self, y):
        """ Convert from a Kiva to a Pyglet y-coordinate.
        Since pyglet uses the same convention as Kiva, this is a no-op.
        """
        return y

    def _on_erase_background(self, event):
        pass

    def _capture_mouse(self):
        "Capture all future mouse events"
        # TODO: Figure out how to do mouse capture.
        # Pyglet's Window class has a set_mouse_exclusive() mode, but this
        # makes the cursur invisible as well.  It really is more of a
        # full-screen "Game Mode", and not designed for mouse capture in a
        # traditional GUI toolkit sense.

        #if not self._mouse_captured:
        #    self.control.set_mouse_exclusive(True)
        #    self._mouse_captured = True
        pass

    def _release_mouse(self):
        "Release the mouse capture"
        #if self._mouse_captured:
        #    self._mouse_captured = False
        #    self.control.set_mouse_exclusive(False)
        pass

    def _create_mouse_event(self, event):
        """ Convert a Pyglet mouse event into an Enable MouseEvent.

        Since Pyglet doesn't actually have a mouse event object like WX or Qt,
        PygletWindow actually does most of the work of creating an Enable
        MouseEvent when various things happen, and calls
        AbstractWindow._handle_mouse_event with that object.
        _handle_mouse_event() then calls this method with that object.

        AbstractWindow._on_window_leave() also calls this method.
        """
        if event is not None:
            x = event.x
            y = event.y
            self._last_mouse_pos = (x, y)
            mouse = pyglet.window.mouse
            buttons = event.buttons
            if buttons is None:
                buttons = 0
            return MouseEvent( x = x, y = y,
                               alt_down     = event.alt_pressed,
                               control_down = event.ctrl_pressed,
                               shift_down   = event.shift_pressed,
                               left_down    = bool(mouse.LEFT & buttons),
                               middle_down  = bool(mouse.MIDDLE & buttons),
                               right_down   = bool(mouse.RIGHT & buttons),
                               mouse_wheel  = event.scroll_y,
                               window = self)
        else:
            # If no event specified, make one up:
            x = self.control._mouse_x
            y = self.control._mouse_y
            self._last_mouse_pos = (x, y)
            return MouseEvent( x = x, y = y,
                               alt_down     = self.alt_pressed,
                               control_down = self.ctrl_pressed,
                               shift_down   = self.shift_pressed,
                               left_down    = False,
                               middle_down  = False,
                               right_down   = False,
                               mouse_wheel  = 0,
                               window = self)

    def _create_gc ( self, size, pix_format = "bgra32" ):
        "Create a Kiva graphics context of a specified size."
        # Unlike the vector-based Agg and Quartz GraphicsContexts which place
        # pixel coordinates at the lower-left corner, the Pyglet backend is
        # raster-based and places coordinates at the center of pixels.
        gc = GraphicsContextEnable(size, window=self)
        gc.init_gl_viewport()
        return gc

    def _redraw(self, coordinates=None):
        "Request a redraw of the window"
        if self.control is not None:
            self.control.request_redraw(coordinates)

    def _get_control_size(self):
        "Get the size of the underlying toolkit control"
        if self.control is not None:
            return self.control.get_size()
        else:
            return None

    def set_pointer(self, pointer):
        "Set the current pointer (i.e. cursor) shape"
        if pointer == "blank":
            self.control.set_mouse_visible(False)
        elif pointer in POINTER_MAP:
            self.control.set_mouse_visible(True)
            cursor = self.control.get_system_mouse_cursor(POINTER_MAP[pointer])
            self.control.set_mouse_cursor(cursor)
        else:
            warnings.warn("Unable to set mouse pointer '%s' in"
                          "Enable's Pyglet backend." % pointer)
            cursor = self.control.get_system_mouse_cursor(POINTER_MAP["arrow"])
            self.control.set_mouse_cursor(cursor)
        return

    def set_timer_interval(self, component, interval):
        """ Set up or cancel a timer for a specified component.  To cancel the
        timer, set interval=None.
        """
        raise NotImplementedError("set_timer_interval() not implemented yet in Pyglet backend.")

    def _set_focus(self):
        """ Sets the keyboard focus to this window.

        Since Pyglet is not a windowing system, there are not other windows we
        might lose focus to; the entire application has focus or it doesn't.
        This attempts to make the application regain focus.
        """
        self.control.activate()

    #-------------------------------------------------------------------------
    # Unnecessary methods but provided for compatibility
    #-------------------------------------------------------------------------

    def _window_paint(self, event):
        "Do a backend-specific screen update"
        # We don't actually have to do anything here.  In other backends
        # where the self.component.draw(gc) call just renders onto an
        # in-screen GraphicsContext, this method is used to do a platform-
        # specific blit.  In the case of Pyglet, the component.draw()
        # method executes immediates on the current OpenGL context, so
        # there is no additional step needed here.
        pass

    def screen_to_window(self, x, y, warn=True):
        """ This method is really not needed for Pyglet, since mouse coords
        are given relative to the window's lower-left corner anyways.
        """
        if warn:
            warnings.warn("screen_to_window() is unnecessary when using Pyglet backend.")
        return (x,y)

    #-------------------------------------------------------------------------
    # Unimplemented or unimplementable methods in Pyglet
    # (These are mostly due to the fact that it is an access layer to GL and
    # not a full GUI toolkit.)
    #-------------------------------------------------------------------------

    def set_tooltip(self, tooltip):
        "Set the current tooltip for the window"
        raise NotImplementedError("No equivalent for set_tooltip() in Pyglet.")

    def create_menu(self, menu_definition, owner):
        "Create a Menu from a string description"
        raise NotImplementedError("create_menu() is not implemented in Pyglet backend.")

    def popup_menu(self, menu, x, y):
        "Pop-up a Menu at a specified location"
        raise NotImplementedError("popup_menu() is not implemented in Pyglet backend.")

<commit_msg>fixing stupid bug in mouse handling in pyglet backend<commit_after>"""
Defines the concrete top-level Enable 'Window' class for the Pyglet framework.
Uses the Kiva GL backend.
"""

import sys
import warnings

# Pyglet imports
import pyglet
from pyglet import window
from pyglet.window import key

# Enthought library imports
from enthought.traits.api import Any, Float, Instance, Trait

# Enable imports
from enthought.enable2.base import send_event_to, union_bounds
from enthought.enable2.component  import Component
from enthought.enable2.events import MouseEvent, KeyEvent, DragEvent
from enthought.enable2.graphics_context import GraphicsContextEnable
from enthought.enable2.abstract_window import AbstractWindow

# local, relative imports
from constants import BUTTON_NAME_MAP, KEY_MAP, POINTER_MAP

class PygletMouseEvent(object):
    """ Because Pyglet doesn't have a native mouse event object, we use
    this to encapsulate all the possible state when we receive any mouse-
    related event.
    """
    def __init__(self, x, y, dx=0, dy=0, buttons=None, modifiers=None,
                 scroll_x=0, scroll_y=0):
        """ **buttons** is a list of buttons """
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.modifiers = modifiers
        self.buttons = buttons
        self.scroll_x = scroll_x
        self.scroll_y = scroll_y

        if modifiers is not None:
            self.shift_pressed = (modifiers & key.MOD_SHIFT)
            self.ctrl_pressed = (modifiers & key.MOD_CTRL)
            self.alt_pressed = (modifiers & key.MOD_ALT)
        else:
            self.shift_pressed = self.ctrl_pressed = self.alt_pressed = False
        return

class PygletWindow(window.Window):
    """ Pyglet recommends subclassing their base Window class as the preferred
    method for customizing behavior.  This PygletWindow class serves to bridge
    events and methods between the Enable layer and Pyglet.

    """

    def __init__(self, enable_window, **kwargs):
        """ PygletWindow needs a reference to the Enable window; other
        arguments are passed through directly to the pyglet.Window constructor.
        """
        self.enable_window = enable_window

        # Whether or not the Enable component stack has requested a redraw
        self._redraw_requested = False

        super(PygletWindow, self).__init__(**kwargs)

        # use a KeyStateHandler to remember the keyboard state.  This
        # is useful since Pyglet separates the notion of keyboard state
        # and character events, and we need to access keyboard state
        # from the on_text handler method.
        self.key_state = key.KeyStateHandler()
        self.push_handlers(self.key_state)

    #-------------------------------------------------------------------------
    # Public methods
    # These are not inherited from/part of the pyglet.window.Window interface
    #-------------------------------------------------------------------------

    def draw(self):
        "Called by the mainloop to perform the actual draw"
        self.enable_window._paint()

    def request_redraw(self, coordinates=None):
        """ Called by **self.enable_window** to request a redraw
        **coordinates** is a tuple (x,y,w,h) of a specific sub-region to
        redraw.
        """
        # TODO: Support the **coordinates** argument
        self._redraw_requested = True

    #-------------------------------------------------------------------------
    # Key/text handling
    #-------------------------------------------------------------------------

    def on_key_press(self, symbol, modifiers):
        return self._on_key_updown(symbol, modifiers, down=False)

    def on_key_release(self, symbol, modifiers):
        return self._on_key_updown(symbol, modifiers)

    def _on_key_updown(self, symbol, modifiers, down=True):
        event = PygletMouseEvent(0, 0, modifiers=modifiers)
        enable_win = self.enable_window
        enable_win.shift_pressed = bool(down & event.shift_pressed)
        enable_win.ctrl_pressed = bool(down & event.ctrl_pressed)
        enable_win.alt_pressed = bool(down & event.alt_pressed)
        # It's important to return False so that the KeyStateHandler
        # can also get this event.
        return False

    def on_text(self, text):
        if self.enable_window.focus_owner is None:
            focus_owner = self.enable_window.component
        else:
            focus_owner = self.enable_window.focus_owner

        if focus_owner is None:
            return

        keys = self.key_state
        enable_event = KeyEvent(character = key,
                          alt_down = keys[key.LALT] | keys[key.RALT],
                          control_down = keys[key.LCTRL] | keys[key.RCTRL],
                          shift_down = keys[key.LSHIFT] | keys[key.RSHIFT],
                          x = self._mouse_x,
                          y = self._mouse_y,
                          window = self.enable_window)
        focus_owner.dispatch(enable_event, "key_pressed")
        return True

    def on_text_motion(self, motion):
        # TODO: See notes.
        pass

    def on_text_motion_select(self, motion):
        # TODO: See notes.
        pass

    #-------------------------------------------------------------------------
    # Mouse handling
    #-------------------------------------------------------------------------

    def on_mouse_motion(self, x, y, dx, dy):
        event = PygletMouseEvent(x, y, dx, dy)
        self.enable_window._handle_mouse_event("mouse_move", event, set_focus=False)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        # TODO: Determine the difference between this and on_mouse_motion;
        # confirm that the correct buttons in **buttons** are down.
        event = PygletMouseEvent(x, y, dx, dy, buttons, modifiers)
        self.enable_window._handle_mouse_event("mouse_move", event, set_focus=False)

    def on_mouse_press(self, x, y, button, modifiers):
        return self._on_mouse_updown(x, y, button, modifiers, "down")

    def on_mouse_release(self, x, y, button, modifiers):
        return self._on_mouse_updown(x, y, button, modifiers, "up")

    def _on_mouse_updown(self, x, y, button, modifiers, which="down"):
        event = PygletMouseEvent(x, y, [button], modifiers)
        mouse = pyglet.window.mouse
        if button == mouse.LEFT:
            name = "left"
        elif button == mouse.MIDDLE:
            name = "middle"
        elif button == mouse.RIGHT:
            name = "right"
        self.enable_window._handle_mouse_event(name+"_"+which, event, set_focus=False)
        # TODO: Confirm that we should consume mouse press/release events
        return True

    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        # TODO: Handle scroll_x
        event = PygletMouseEvent(x, y, scroll_x=scroll_x, scroll_y=scroll_y)
        self.enable_window._handle_mouse_event("mouse_wheel", event, set_focus=False)

    def on_mouse_enter(self, x, y):
        event = PygletMouseEvent(x, y)
        self.enable_window._handle_mouse_event("mouse_enter", event, set_focus=False)

    def on_mouse_leave(self, x, y):
        event = PygletMouseEvent(x, y)
        self.enable_window._handle_mouse_event("mouse_leave", event, set_focus=False)

    #-------------------------------------------------------------------------
    # Window
    #-------------------------------------------------------------------------

    def on_resize(self, width, height):
        self.enable_window.resized = (width, height)
        component = self.enable_window.component
        if hasattr(component, "fit_window") and component.fit_window:
            component.outer_position = [0,0]
            component.outer_bounds = [width, height]
        elif hasattr(component, "resizable"):
            if "h" in component.resizable:
                component.outer_x = 0
                component.outer_width = width
            if "v" in component.resizable:
                component.outer_y = 0
                component.outer_height = height
        return

    def on_close(self):
        pass

    def on_expose(self):
        pass

    def on_move(self, x, y):
        """The window was moved.  x is the distance from the left edge of the
        screen to the left edge of the window.  y is the distance from the top
        edge of the screen to the top edge of the window.
        """
        pass

    def on_activate(self):
        """ The window was activated. """
        pass

    def on_deactivate(self):
        """ The window lost focus. """
        pass

    def on_show(self):
        """ The window was shown. """
        pass

    def on_hide(self):
        """ The window was minimized or hidden. """
        pass

    #-------------------------------------------------------------------------
    # GL context stuff - see the pyglet.window.Window documentation on these
    # methods
    #-------------------------------------------------------------------------

    def on_context_lost(self):
        pass

    def on_context_state_lost(self):
        pass

class Window(AbstractWindow):

    _cursor_color = Any  # PZW: figure out the correct type for this...

    # This is set by downstream components to notify us of whether or not
    # the current drag operation should return DragCopy, DragMove, or DragNone.
    _drag_result = Any

    def __init__(self, parent=None, id=-1, **traits ):
        """ **parent** is an unneeded argument with the pyface backend, but
        we need to preserve compatibility with other AbstractWindow
        subclasses.
        """
        # TODO: Fix fact that other backends' Window classes use positional
        # arguments

        self.control = None
        AbstractWindow.__init__(self, **traits)
        self._mouse_captured = False

        # Due to wx wonkiness, we don't reliably get cursor position from
        # a wx KeyEvent.  Thus, we manually keep track of when we last saw
        # the mouse and use that information instead.  These coordinates are
        # in the wx coordinate space, i.e. pre-self._flip_y().
        self._last_mouse_pos = (0, 0)

        # Create the underlying control.
        self.control = PygletWindow(enable_window=self)

        return

    def _flip_y(self, y):
        """ Convert from a Kiva to a Pyglet y-coordinate.
        Since pyglet uses the same convention as Kiva, this is a no-op.
        """
        return y

    def _on_erase_background(self, event):
        pass

    def _capture_mouse(self):
        "Capture all future mouse events"
        # TODO: Figure out how to do mouse capture.
        # Pyglet's Window class has a set_mouse_exclusive() mode, but this
        # makes the cursur invisible as well.  It really is more of a
        # full-screen "Game Mode", and not designed for mouse capture in a
        # traditional GUI toolkit sense.

        #if not self._mouse_captured:
        #    self.control.set_mouse_exclusive(True)
        #    self._mouse_captured = True
        pass

    def _release_mouse(self):
        "Release the mouse capture"
        #if self._mouse_captured:
        #    self._mouse_captured = False
        #    self.control.set_mouse_exclusive(False)
        pass

    def _create_mouse_event(self, event):
        """ Convert a Pyglet mouse event into an Enable MouseEvent.

        Since Pyglet doesn't actually have a mouse event object like WX or Qt,
        PygletWindow actually does most of the work of creating an Enable
        MouseEvent when various things happen, and calls
        AbstractWindow._handle_mouse_event with that object.
        _handle_mouse_event() then calls this method with that object.

        AbstractWindow._on_window_leave() also calls this method.
        """
        if event is not None:
            x = event.x
            y = event.y
            self._last_mouse_pos = (x, y)
            mouse = pyglet.window.mouse
            buttons = event.buttons
            if buttons is None:
                buttons = 0
            return MouseEvent( x = x, y = y,
                               alt_down     = event.alt_pressed,
                               control_down = event.ctrl_pressed,
                               shift_down   = event.shift_pressed,
                               left_down    = bool(mouse.LEFT & buttons),
                               middle_down  = bool(mouse.MIDDLE & buttons),
                               right_down   = bool(mouse.RIGHT & buttons),
                               mouse_wheel  = event.scroll_y,
                               window = self)
        else:
            # If no event specified, make one up:
            x = self.control._mouse_x
            y = self.control._mouse_y
            self._last_mouse_pos = (x, y)
            return MouseEvent( x = x, y = y,
                               alt_down     = self.alt_pressed,
                               control_down = self.ctrl_pressed,
                               shift_down   = self.shift_pressed,
                               left_down    = False,
                               middle_down  = False,
                               right_down   = False,
                               mouse_wheel  = 0,
                               window = self)

    def _create_gc ( self, size, pix_format = "bgra32" ):
        "Create a Kiva graphics context of a specified size."
        # Unlike the vector-based Agg and Quartz GraphicsContexts which place
        # pixel coordinates at the lower-left corner, the Pyglet backend is
        # raster-based and places coordinates at the center of pixels.
        gc = GraphicsContextEnable(size, window=self)
        gc.init_gl_viewport()
        return gc

    def _redraw(self, coordinates=None):
        "Request a redraw of the window"
        if self.control is not None:
            self.control.request_redraw(coordinates)

    def _get_control_size(self):
        "Get the size of the underlying toolkit control"
        if self.control is not None:
            return self.control.get_size()
        else:
            return None

    def set_pointer(self, pointer):
        "Set the current pointer (i.e. cursor) shape"
        if pointer == "blank":
            self.control.set_mouse_visible(False)
        elif pointer in POINTER_MAP:
            self.control.set_mouse_visible(True)
            cursor = self.control.get_system_mouse_cursor(POINTER_MAP[pointer])
            self.control.set_mouse_cursor(cursor)
        else:
            warnings.warn("Unable to set mouse pointer '%s' in"
                          "Enable's Pyglet backend." % pointer)
            cursor = self.control.get_system_mouse_cursor(POINTER_MAP["arrow"])
            self.control.set_mouse_cursor(cursor)
        return

    def set_timer_interval(self, component, interval):
        """ Set up or cancel a timer for a specified component.  To cancel the
        timer, set interval=None.
        """
        raise NotImplementedError("set_timer_interval() not implemented yet in Pyglet backend.")

    def _set_focus(self):
        """ Sets the keyboard focus to this window.

        Since Pyglet is not a windowing system, there are not other windows we
        might lose focus to; the entire application has focus or it doesn't.
        This attempts to make the application regain focus.
        """
        self.control.activate()

    #-------------------------------------------------------------------------
    # Unnecessary methods but provided for compatibility
    #-------------------------------------------------------------------------

    def _window_paint(self, event):
        "Do a backend-specific screen update"
        # We don't actually have to do anything here.  In other backends
        # where the self.component.draw(gc) call just renders onto an
        # in-screen GraphicsContext, this method is used to do a platform-
        # specific blit.  In the case of Pyglet, the component.draw()
        # method executes immediates on the current OpenGL context, so
        # there is no additional step needed here.
        pass

    def screen_to_window(self, x, y, warn=True):
        """ This method is really not needed for Pyglet, since mouse coords
        are given relative to the window's lower-left corner anyways.
        """
        if warn:
            warnings.warn("screen_to_window() is unnecessary when using Pyglet backend.")
        return (x,y)

    #-------------------------------------------------------------------------
    # Unimplemented or unimplementable methods in Pyglet
    # (These are mostly due to the fact that it is an access layer to GL and
    # not a full GUI toolkit.)
    #-------------------------------------------------------------------------

    def set_tooltip(self, tooltip):
        "Set the current tooltip for the window"
        raise NotImplementedError("No equivalent for set_tooltip() in Pyglet.")

    def create_menu(self, menu_definition, owner):
        "Create a Menu from a string description"
        raise NotImplementedError("create_menu() is not implemented in Pyglet backend.")

    def popup_menu(self, menu, x, y):
        "Pop-up a Menu at a specified location"
        raise NotImplementedError("popup_menu() is not implemented in Pyglet backend.")

<|endoftext|>


<commit_before>from enthought.util.numerix import *
import unittest
import Image
import sys

from enthought.kiva import agg

def save(img,file_name):
    """ This only saves the rgb channels of the image
    """
    format = img.format()
    if format == "bgra32":
        size = img.bmp_array.shape[1],img.bmp_array.shape[0]
        bgr = img.bmp_array[:,:,:3]
        rgb = bgr[:,:,::-1].copy()
        st = rgb.tostring()
        pil_img = Image.fromstring("RGB",size,st)
        pil_img.save(file_name)
    else:
        raise NotImplementedError, "currently only supports writing out bgra32 images"

class TestDrawDash(unittest.TestCase):
    def check_dash(self):
        gc = agg.GraphicsContextArray((100,100))
        gc.set_line_dash([2,2])
        for i in range(10):
            gc.move_to(0,0)
            gc.line_to(0,100)
            gc.stroke_path()
            gc.translate_ctm(10,0)
        save(gc,'dash.bmp')

def test_suite(level=1):
    suites = []
    if level > 0:
        suites.append( unittest.makeSuite(TestDrawDash,'check_') )
    total_suite = unittest.TestSuite(suites)
    return total_suite

def test(level=10):
    all_tests = test_suite(level)
    runner = unittest.TextTestRunner()
    runner.run(all_tests)
    return runner

if __name__ == "__main__":
    test()
<commit_msg>fixed<commit_after>import sys
import unittest

import numpy
import Image

from enthought.kiva import agg

def save(img,file_name):
    """ This only saves the rgb channels of the image
    """
    format = img.format()
    if format == "bgra32":
        size = img.bmp_array.shape[1],img.bmp_array.shape[0]
        bgr = img.bmp_array[:,:,:3]
        rgb = bgr[:,:,::-1].copy()
        st = rgb.tostring()
        pil_img = Image.fromstring("RGB",size,st)
        pil_img.save(file_name)
    else:
        raise NotImplementedError("currently only supports writing out "
                                  "bgra32 images")

class TestDrawDash(unittest.TestCase):
    def test_dash(self):
        gc = agg.GraphicsContextArray((100,100))
        gc.set_line_dash([2,2])
        for i in range(10):
            gc.move_to(0,0)
            gc.line_to(0,100)
            gc.stroke_path()
            gc.translate_ctm(10,0)
        save(gc,'dash.bmp')

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


<commit_before>import inviwopy
# import inviwopy.glm as glm
import numpy as np
import h5py
from envisionpy.utils.exceptions import *
from .baseNetworks.VolumeSubnetwork import VolumeSubnetwork

# TODO: add self.volume_outport with a merged version of all the
#       volumes. Use a VolumeCombiner processor and input all volumes
#       add data divide by number of volumes. Output of this is volume_outport
#       This will allow the visualisation to be used with the multi volume vis.

class PartialChargeDensity(VolumeSubnetwork):
    '''
    Manages a subnetwork for partial charge density visualisation.
    Makes use of a modified VolumeSubnetwork. Has a different volume selection than
    the default VolumeSubnetwork implementation to allow selection of different bands
    and modes.

    Based on VolumeSubnetwork.
    '''
    def __init__(self, inviwoApp, hdf5_path, hdf5_outport, xpos=0, ypos=0, band_list=[], mode_list=[]):
        # Initialize a volume subnetwork with multichannel raycaster
        VolumeSubnetwork.__init__(self, inviwoApp, hdf5_path, hdf5_outport, xpos, ypos+6, True)
        self.set_hdf5_subpath('PARCHG/Bands')

        # Available bands and modes in hdf5 file.
        self.available_bands = []
        self.available_modes = []
        with h5py.File(hdf5_path, 'r') as file:
            for key in file.get("PARCHG/Bands").keys():
                self.available_bands.append(key)
            for key in file.get("PARCHG/Bands")[self.available_bands[0]].keys():
                self.available_modes.append(key)
            if ("magnetic" in self.available_modes) and ("total" in self.available_modes):
                self.available_modes += ["up", "down"]

            # self.set_basis(np.array(h5["/basis/"], dtype='d'), h5['/scaling_factor'][()])

        self.current_bands = []
        self.current_modes = []

        self.volume_processors = []
        self.basis_props = []
        self.basis_3x3 = [[1,0,0],[0,1,0],[0,0,1]]
        self.basis_scale = 1

        # Modify network for parchg visualisation.
        self.modify_network(hdf5_path, hdf5_outport, xpos, ypos)
        self.select_bands(band_list, mode_list, xpos+1, ypos)

        with h5py.File(hdf5_path, "r") as h5:
            self.set_basis(np.array(h5["/basis/"], dtype='d'), h5['/scaling_factor'][()])

        # Set some default parameters for charge visualisation.
        self.add_tf_point(0.45, [0.1, 0.1, 0.8, 0.05])
        self.add_tf_point(0.5, [0.2, 0.8, 0.1, 0.1])
        self.add_tf_point(0.8, [0.9, 0.1, 0.1, 0.5])

    @staticmethod
    def valid_hdf5(hdf5_file):
        return hdf5_file.get("PARCHG") != None

    def valid_decorations(self):
        return ['atom']

    def connect_decoration(self, other, vis_type):
        if vis_type not in self.valid_decorations():
            raise EnvisionError('Invalid decoration type ['+vis_type+'].')
        # Link needed properties between networks.
        if vis_type == 'atom':
            self.network.addLink(self.camera_prop, other.camera_prop)
        self.connect_decoration_ports(other.decoration_outport)

    def disconnect_decoration(self, other, vis_type):
        if vis_type == 'atom':
            self.network.removeLink(self.camera_prop, other.camera_prop)
        self.disconnect_decorations_port(other.decoration_outport)

    def get_available_modes(self):
        return self.available_modes

    def get_available_bands(self):
        return self.available_bands

    def get_partial_selections(self):
        return [self.current_bands, self.current_modes]

# ------------------------------------------
# ------- Property control functions -------

    def set_basis(self, basis_3x3, scale=1):
        self.basis_3x3 = basis_3x3
        basis_4x4 = np.identity(4)
        basis_4x4[:3,:3] = basis_3x3
        basis_4x4 = np.multiply(scale, basis_4x4)
        minValue = inviwopy.glm.mat4(
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000)
        maxValue = inviwopy.glm.mat4(
            1000,1000,1000,1000,
            1000,1000,1000,1000,
            1000,1000,1000,1000,
            1000,1000,1000,1000)
        value = inviwopy.glm.mat4(*basis_4x4.flatten())
        for basis_prop in self.basis_props:
            basis_prop.minValue = minValue
            basis_prop.maxValue = maxValue
            basis_prop.value = value

        meshCreator = self.get_processor('MeshCreator')
        meshCreator.scale.value = scale

# ------------------------------------------
# ------- Network building functions -------

    def select_bands(self, band_list, mode_list, xpos=1, ypos=0):
        # Connect and merge up to 4 different volumes with the different modes.

        # Validate input.
        if len(band_list) != len(mode_list):
            raise EnvisionError('Mode list must be same length as band list for partial charge visualisation.')
        if len(band_list) > 4:
            raise EnvisionError('A maximum of 4 volumes can be used at one time for partial charge visualisation.')
        for mode in mode_list:
            if mode not in self.available_modes:
                raise EnvisionError('Unavailable mode. Data for [' + str(mode) + '] mode not in hdf5 file.')
        for band in band_list:
            if str(band) not in self.available_bands:
                raise EnvisionError('Unavailable band. Data for band [' + str(band) + '] not in hdf5 file.')

        self.current_bands = band_list
        self.current_modes = mode_list

        # Clear any old volume selection
        for processor in self.volume_processors:
            self.remove_processor_by_ref(processor)
        self.basis_props.clear()
        self.volume_processors.clear()

        # Set up new volume selections according to band and mode selections.
        hdf5_inports = []
        volume_outports = []
        for i in range(len(band_list)):
            if mode_list[i] == 'total' or mode_list[i] == 'magnetic':
                volumeTotal = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' ' + mode_list[i], xpos+7*(i+1), ypos+3)
                self.basis_props.append(volumeTotal.basisGroup.basis)
                self.volume_processors.append(volumeTotal)
                hdf5_inports.append(volumeTotal.getInport('inport'))
                volume_outports.append(volumeTotal.getOutport('outport'))
            else:
                volumeInPlus = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' total', xpos+7*(i+1), ypos+3)
                volumeInMinus = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' magnetic', xpos-1+7*(i+1) , ypos+6)
                volumeCombine = self.add_processor('org.inviwo.VolumeCombiner', 'Band ' + str(band_list[i]) + ' ' + mode_list[i], xpos+7*(i+1), ypos+9)

                self.network.addConnection(volumeInPlus.getOutport('outport'), volumeCombine.getInport('inport'))
                self.network.addConnection(volumeInMinus.getOutport('outport'), volumeCombine.getInport('inport'))

                if mode_list[i] == 'up':
                    volumeCombine.eqn.value = '0.5*(v1+v2)'
                if mode_list[i] == 'down':
                    volumeCombine.eqn.value = '0.5*(v1-v2)'

                self.basis_props.append(volumeInPlus.basisGroup.basis)
                self.basis_props.append(volumeInMinus.basisGroup.basis)
                hdf5_inports.append(volumeInPlus.getInport('inport'))
                hdf5_inports.append(volumeInMinus.getInport('inport'))
                volume_outports.append(volumeCombine.getOutport('outport'))
                self.volume_processors += [volumeInPlus, volumeInMinus, volumeCombine]

        self.set_basis(self.basis_3x3, self.basis_scale)

        # Connect the hdf5 inports and volume outports.
        hdf5Path = self.get_processor('HDF5 path')
        merger = self.get_processor('VolumeMerger')
        volume_inports = [
            merger.getInport('inputVolume'), merger.getInport('volume2'),
            merger.getInport('volume3'), merger.getInport('volume4')]
        for inport in hdf5_inports:
            self.network.addConnection(hdf5Path.getOutport('outport'), inport)
        for i in range(len(volume_outports)):
            self.network.addConnection(volume_outports[i], volume_inports[i])

    def modify_network(self, hdf5_path, hdf5_output, xpos, ypos):
        # Change the volume selection compared to the default volume network.

        # Remove hdf5ToVolume processor.
        self.remove_processor('Hdf5Selection')

        # Create and connect volume merger.
        merger = self.add_processor('org.inviwo.VolumeMerger', 'VolumeMerger', xpos, ypos + 9)

        isoRaycaster = self.get_processor('IsoRaycaster')
        boundingBox = self.get_processor('Volume Bounding Box')
        cubeProxy = self.get_processor('Cube Proxy Geometry')
        raycaster = self.get_processor('Raycaster')
        volumeSlice = self.get_processor('VolumeSlice')

        self.network.addConnection(merger.getOutport('outputVolume'), boundingBox.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), cubeProxy.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), raycaster.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), volumeSlice.getInport('volume'))
        if self.is_multichannel:
            isoRaycaster = self.get_processor('IsoRaycaster')
            self.network.addConnection(merger.getOutport('outputVolume'), isoRaycaster.getInport('volume'))

<commit_msg>fixed basis not updating<commit_after>import inviwopy
# import inviwopy.glm as glm
import numpy as np
import h5py
from envisionpy.utils.exceptions import *
from .baseNetworks.VolumeSubnetwork import VolumeSubnetwork

# TODO: add self.volume_outport with a merged version of all the
#       volumes. Use a VolumeCombiner processor and input all volumes
#       add data divide by number of volumes. Output of this is volume_outport
#       This will allow the visualisation to be used with the multi volume vis.

class PartialChargeDensity(VolumeSubnetwork):
    '''
    Manages a subnetwork for partial charge density visualisation.
    Makes use of a modified VolumeSubnetwork. Has a different volume selection than
    the default VolumeSubnetwork implementation to allow selection of different bands
    and modes.

    Based on VolumeSubnetwork.
    '''
    def __init__(self, inviwoApp, hdf5_path, hdf5_outport, xpos=0, ypos=0, band_list=[], mode_list=[]):
        # Initialize a volume subnetwork with multichannel raycaster
        VolumeSubnetwork.__init__(self, inviwoApp, hdf5_path, hdf5_outport, xpos, ypos+6, True)
        self.set_hdf5_subpath('PARCHG/Bands')

        # Available bands and modes in hdf5 file.
        self.available_bands = []
        self.available_modes = []
        with h5py.File(hdf5_path, 'r') as file:
            for key in file.get("PARCHG/Bands").keys():
                self.available_bands.append(key)
            for key in file.get("PARCHG/Bands")[self.available_bands[0]].keys():
                self.available_modes.append(key)
            if ("magnetic" in self.available_modes) and ("total" in self.available_modes):
                self.available_modes += ["up", "down"]

            # self.set_basis(np.array(h5["/basis/"], dtype='d'), h5['/scaling_factor'][()])

        self.current_bands = []
        self.current_modes = []

        self.volume_processors = []
        self.basis_props = []
        self.basis_3x3 = [[1,0,0],[0,1,0],[0,0,1]]
        self.basis_scale = 1

        # Modify network for parchg visualisation.
        self.modify_network(hdf5_path, hdf5_outport, xpos, ypos)
        self.select_bands(band_list, mode_list, xpos+1, ypos)

        with h5py.File(hdf5_path, "r") as h5:
            self.set_basis(np.array(h5["/basis/"], dtype='d'), h5['/scaling_factor'][()])

        # Set some default parameters for charge visualisation.
        self.add_tf_point(0.45, [0.1, 0.1, 0.8, 0.05])
        self.add_tf_point(0.5, [0.2, 0.8, 0.1, 0.1])
        self.add_tf_point(0.8, [0.9, 0.1, 0.1, 0.5])

    @staticmethod
    def valid_hdf5(hdf5_file):
        return hdf5_file.get("PARCHG") != None

    def valid_decorations(self):
        return ['atom']

    def connect_decoration(self, other, vis_type):
        if vis_type not in self.valid_decorations():
            raise EnvisionError('Invalid decoration type ['+vis_type+'].')
        # Link needed properties between networks.
        if vis_type == 'atom':
            self.network.addLink(self.camera_prop, other.camera_prop)
        self.connect_decoration_ports(other.decoration_outport)

    def disconnect_decoration(self, other, vis_type):
        if vis_type == 'atom':
            self.network.removeLink(self.camera_prop, other.camera_prop)
        self.disconnect_decorations_port(other.decoration_outport)

    def get_available_modes(self):
        return self.available_modes

    def get_available_bands(self):
        return self.available_bands

    def get_partial_selections(self):
        return [self.current_bands, self.current_modes]

# ------------------------------------------
# ------- Property control functions -------

    def set_basis(self, basis_3x3, scale=1):
        self.basis_3x3 = basis_3x3
        self.basis_scale = scale
        basis_4x4 = np.identity(4)
        basis_4x4[:3,:3] = basis_3x3
        basis_4x4 = np.multiply(scale, basis_4x4)
        minValue = inviwopy.glm.mat4(
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000,
            -1000,-1000,-1000,-1000)
        maxValue = inviwopy.glm.mat4(
            1000,1000,1000,1000,
            1000,1000,1000,1000,
            1000,1000,1000,1000,
            1000,1000,1000,1000)
        value = inviwopy.glm.mat4(*basis_4x4.flatten())
        for basis_prop in self.basis_props:
            basis_prop.minValue = minValue
            basis_prop.maxValue = maxValue
            basis_prop.value = value

        meshCreator = self.get_processor('MeshCreator')
        meshCreator.scale.value = scale

# ------------------------------------------
# ------- Network building functions -------

    def select_bands(self, band_list, mode_list, xpos=1, ypos=0):
        # Connect and merge up to 4 different volumes with the different modes.

        # Validate input.
        if len(band_list) != len(mode_list):
            raise EnvisionError('Mode list must be same length as band list for partial charge visualisation.')
        if len(band_list) > 4:
            raise EnvisionError('A maximum of 4 volumes can be used at one time for partial charge visualisation.')
        for mode in mode_list:
            if mode not in self.available_modes:
                raise EnvisionError('Unavailable mode. Data for [' + str(mode) + '] mode not in hdf5 file.')
        for band in band_list:
            if str(band) not in self.available_bands:
                raise EnvisionError('Unavailable band. Data for band [' + str(band) + '] not in hdf5 file.')

        self.current_bands = band_list
        self.current_modes = mode_list

        # Clear any old volume selection
        for processor in self.volume_processors:
            self.remove_processor_by_ref(processor)
        self.basis_props.clear()
        self.volume_processors.clear()

        # Set up new volume selections according to band and mode selections.
        hdf5_inports = []
        volume_outports = []
        for i in range(len(band_list)):
            if mode_list[i] == 'total' or mode_list[i] == 'magnetic':
                volumeTotal = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' ' + mode_list[i], xpos+7*(i+1), ypos+3)
                self.basis_props.append(volumeTotal.basisGroup.basis)
                self.volume_processors.append(volumeTotal)
                hdf5_inports.append(volumeTotal.getInport('inport'))
                volume_outports.append(volumeTotal.getOutport('outport'))
            else:
                volumeInPlus = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' total', xpos+7*(i+1), ypos+3)
                volumeInMinus = self.add_processor('org.inviwo.hdf5.ToVolume', 'Band ' + str(band_list[i]) + ' magnetic', xpos-1+7*(i+1) , ypos+6)
                volumeCombine = self.add_processor('org.inviwo.VolumeCombiner', 'Band ' + str(band_list[i]) + ' ' + mode_list[i], xpos+7*(i+1), ypos+9)

                self.network.addConnection(volumeInPlus.getOutport('outport'), volumeCombine.getInport('inport'))
                self.network.addConnection(volumeInMinus.getOutport('outport'), volumeCombine.getInport('inport'))

                if mode_list[i] == 'up':
                    volumeCombine.eqn.value = '0.5*(v1+v2)'
                if mode_list[i] == 'down':
                    volumeCombine.eqn.value = '0.5*(v1-v2)'

                self.basis_props.append(volumeInPlus.basisGroup.basis)
                self.basis_props.append(volumeInMinus.basisGroup.basis)
                hdf5_inports.append(volumeInPlus.getInport('inport'))
                hdf5_inports.append(volumeInMinus.getInport('inport'))
                volume_outports.append(volumeCombine.getOutport('outport'))
                self.volume_processors += [volumeInPlus, volumeInMinus, volumeCombine]

        self.set_basis(self.basis_3x3, self.basis_scale)

        # Connect the hdf5 inports and volume outports.
        hdf5Path = self.get_processor('HDF5 path')
        merger = self.get_processor('VolumeMerger')
        volume_inports = [
            merger.getInport('inputVolume'), merger.getInport('volume2'),
            merger.getInport('volume3'), merger.getInport('volume4')]
        for inport in hdf5_inports:
            self.network.addConnection(hdf5Path.getOutport('outport'), inport)
        for i in range(len(volume_outports)):
            self.network.addConnection(volume_outports[i], volume_inports[i])

    def modify_network(self, hdf5_path, hdf5_output, xpos, ypos):
        # Change the volume selection compared to the default volume network.

        # Remove hdf5ToVolume processor.
        self.remove_processor('Hdf5Selection')

        # Create and connect volume merger.
        merger = self.add_processor('org.inviwo.VolumeMerger', 'VolumeMerger', xpos, ypos + 9)

        isoRaycaster = self.get_processor('IsoRaycaster')
        boundingBox = self.get_processor('Volume Bounding Box')
        cubeProxy = self.get_processor('Cube Proxy Geometry')
        raycaster = self.get_processor('Raycaster')
        volumeSlice = self.get_processor('VolumeSlice')

        self.network.addConnection(merger.getOutport('outputVolume'), boundingBox.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), cubeProxy.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), raycaster.getInport('volume'))
        self.network.addConnection(merger.getOutport('outputVolume'), volumeSlice.getInport('volume'))
        if self.is_multichannel:
            isoRaycaster = self.get_processor('IsoRaycaster')
            self.network.addConnection(merger.getOutport('outputVolume'), isoRaycaster.getInport('volume'))

<|endoftext|>