<commit_before># -*- coding: utf-8 -*-
#
# Copyright (c) 2016 NORDUnet A/S
# Copyright (c) 2019 SUNET
# All rights reserved.
#
#   Redistribution and use in source and binary forms, with or
#   without modification, are permitted provided that the following
#   conditions are met:
#
#     1. Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     2. Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided
#        with the distribution.
#     3. Neither the name of the NORDUnet nor the names of its
#        contributors may be used to endorse or promote products derived
#        from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import os
import json
from datetime import datetime, timedelta

from mock import patch
import flask.testing

from eduid_common.api.testing import EduidAPITestCase
from eduid_common.config.parsers.etcd import EtcdConfigParser

from eduid_webapp.jsconfig.app import jsconfig_init_app
from eduid_webapp.jsconfig.settings.common import JSConfigConfig
from eduid_webapp.jsconfig.settings.front import FrontConfig

class JSConfigTests(EduidAPITestCase):

    def setUp(self):
        super(JSConfigTests, self).setUp(copy_user_to_private=False)

        self.jsconfig_ns = '/eduid/webapp/jsapps/'
        self.jsconfig_parser = EtcdConfigParser(namespace=self.jsconfig_ns,
                                                host=self.etcd_instance.host,
                                                port=self.etcd_instance.port)

        jsconfig_config = {
            'eduid': {
                'webapp': {
                    'jsapps': {
                        'password_entropy': 12,
                        'password_length': 10,
                        'dashboard_url': 'dummy-url'
                    }
                }
            }
        }
        self.jsconfig_parser.write_configuration(jsconfig_config)
        os.environ['EDUID_CONFIG_NS'] = '/eduid/webapp/jsapps/'
        os.environ['ETCD_HOST'] = self.etcd_instance.host
        os.environ['ETCD_PORT'] = str(self.etcd_instance.port)

    def load_app(self, config):
        """
        Called from the parent class, so we can provide the appropriate flask
        app for this test case.
        """
        app = jsconfig_init_app('jsconfig', config)
        self.browser = app.test_client(allow_subdomain_redirects=True)
        app.url_map.host_matching = False
        return app

    def update_config(self, app_config):
        app_config.update({
            'server_name': 'example.com',
            'tou_url': 'dummy-url',
            'testing': True,
            'dashboard_bundle_path': 'dummy-dashboard-bundle',
            'dashboard_bundle_version': 'dummy-dashboard-version',
            'signup_bundle_path': 'dummy-signup-bundle',
            'signup_bundle_version': 'dummy-signup-version',
            'login_bundle_path': 'dummy-login-bundle',
            'login_bundle_version': 'dummy-login-version',
        })
        return JSConfigConfig(**app_config)

    def test_get_dashboard_config(self):
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='dashboard') as client:
            response = client.get('http://dashboard.example.com/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['dashboard_url'], 'dummy-url')
            self.assertEqual(config_data['payload']['static_faq_url'], '')

    @patch('eduid_webapp.jsconfig.views.requests.get')
    def test_get_signup_config(self, mock_request_get):

        class MockResponse:
            status_code = 200
            headers = {'mock-header': 'dummy-value'}
            def json(self):
                return {
                        'payload': {
                            'test-version-1': '1st Dummy TOU',
                            'test-version-2': '2st Dummy TOU',
                            }
                        }

        mock_request_get.return_value = MockResponse()

        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='signup') as client:
            response = client.get('http://signup.example.com/signup/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_SIGNUP_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['dashboard_url'], 'dummy-url')
            self.assertEqual(config_data['payload']['static_faq_url'], '')
            self.assertEqual(config_data['payload']['tous']['test-version-2'], '2st Dummy TOU')

    def test_get_login_config(self):

        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='login') as client:
            response = client.get('http://login.example.com/login/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_LOGIN_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['password_entropy'], 12)
            self.assertEqual(config_data['payload']['password_length'], 10)

    def test_get_dashboard_bundle(self):
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='dashboard') as client:
            response = client.get('http://dashboard.example.com/get-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-dashboard-bundle' in str(body))
            self.assertTrue('dummy-dashboard-version' in str(body))

# XXX the tests below are wrong, they should not be testing for dummy-dashboard
# but for dummy-login and dummy-signup.
# the problem is that the test browser does not play well with subdomains.
# So they should be commented out, in which case, codecov does not allow the
# PR.

    def test_get_signup_bundle(self):
        # XXX Here we access the view by exposing it in a different path - the
        # production manner of distinguishing it (throught its subdomain) does
        # not work with the test client
        from eduid_webapp.jsconfig import views
        views.jsconfig_views.route('/get-signup-bundle', methods=['GET'])(views.get_signup_bundle)
        self.app.register_blueprint(views.jsconfig_views)
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn) as client:
            response = client.get('http://signup.example.com/get-signup-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-signup-bundle' in str(body))
            self.assertTrue('dummy-signup-version' in str(body))

    def test_get_login_bundle(self):
        # XXX Here we access the view by exposing it in a different path - the
        # production manner of distinguishing it (throught its subdomain) does
        # not work with the test client
        from eduid_webapp.jsconfig import views
        views.jsconfig_views.route('/get-login-bundle', methods=['GET'])(views.get_login_bundle)
        self.app.register_blueprint(views.jsconfig_views)
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn) as client:
            response = client.get('http://login.example.com/get-login-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-login-bundle' in str(body))
            self.assertTrue('dummy-login-version' in str(body))
<commit_msg>rm obsolete comment<commit_after># -*- coding: utf-8 -*-
#
# Copyright (c) 2016 NORDUnet A/S
# Copyright (c) 2019 SUNET
# All rights reserved.
#
#   Redistribution and use in source and binary forms, with or
#   without modification, are permitted provided that the following
#   conditions are met:
#
#     1. Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     2. Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided
#        with the distribution.
#     3. Neither the name of the NORDUnet nor the names of its
#        contributors may be used to endorse or promote products derived
#        from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import os
import json
from datetime import datetime, timedelta

from mock import patch
import flask.testing

from eduid_common.api.testing import EduidAPITestCase
from eduid_common.config.parsers.etcd import EtcdConfigParser

from eduid_webapp.jsconfig.app import jsconfig_init_app
from eduid_webapp.jsconfig.settings.common import JSConfigConfig
from eduid_webapp.jsconfig.settings.front import FrontConfig

class JSConfigTests(EduidAPITestCase):

    def setUp(self):
        super(JSConfigTests, self).setUp(copy_user_to_private=False)

        self.jsconfig_ns = '/eduid/webapp/jsapps/'
        self.jsconfig_parser = EtcdConfigParser(namespace=self.jsconfig_ns,
                                                host=self.etcd_instance.host,
                                                port=self.etcd_instance.port)

        jsconfig_config = {
            'eduid': {
                'webapp': {
                    'jsapps': {
                        'password_entropy': 12,
                        'password_length': 10,
                        'dashboard_url': 'dummy-url'
                    }
                }
            }
        }
        self.jsconfig_parser.write_configuration(jsconfig_config)
        os.environ['EDUID_CONFIG_NS'] = '/eduid/webapp/jsapps/'
        os.environ['ETCD_HOST'] = self.etcd_instance.host
        os.environ['ETCD_PORT'] = str(self.etcd_instance.port)

    def load_app(self, config):
        """
        Called from the parent class, so we can provide the appropriate flask
        app for this test case.
        """
        app = jsconfig_init_app('jsconfig', config)
        self.browser = app.test_client(allow_subdomain_redirects=True)
        app.url_map.host_matching = False
        return app

    def update_config(self, app_config):
        app_config.update({
            'server_name': 'example.com',
            'tou_url': 'dummy-url',
            'testing': True,
            'dashboard_bundle_path': 'dummy-dashboard-bundle',
            'dashboard_bundle_version': 'dummy-dashboard-version',
            'signup_bundle_path': 'dummy-signup-bundle',
            'signup_bundle_version': 'dummy-signup-version',
            'login_bundle_path': 'dummy-login-bundle',
            'login_bundle_version': 'dummy-login-version',
        })
        return JSConfigConfig(**app_config)

    def test_get_dashboard_config(self):
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='dashboard') as client:
            response = client.get('http://dashboard.example.com/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['dashboard_url'], 'dummy-url')
            self.assertEqual(config_data['payload']['static_faq_url'], '')

    @patch('eduid_webapp.jsconfig.views.requests.get')
    def test_get_signup_config(self, mock_request_get):

        class MockResponse:
            status_code = 200
            headers = {'mock-header': 'dummy-value'}
            def json(self):
                return {
                        'payload': {
                            'test-version-1': '1st Dummy TOU',
                            'test-version-2': '2st Dummy TOU',
                            }
                        }

        mock_request_get.return_value = MockResponse()

        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='signup') as client:
            response = client.get('http://signup.example.com/signup/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_SIGNUP_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['dashboard_url'], 'dummy-url')
            self.assertEqual(config_data['payload']['static_faq_url'], '')
            self.assertEqual(config_data['payload']['tous']['test-version-2'], '2st Dummy TOU')

    def test_get_login_config(self):

        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='login') as client:
            response = client.get('http://login.example.com/login/config')

            self.assertEqual(response.status_code, 200)

            config_data = json.loads(response.data)

            self.assertEqual(config_data['type'], 'GET_JSCONFIG_LOGIN_CONFIG_SUCCESS')
            self.assertEqual(config_data['payload']['password_entropy'], 12)
            self.assertEqual(config_data['payload']['password_length'], 10)

    def test_get_dashboard_bundle(self):
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn, server_name='example.com',
                                 subdomain='dashboard') as client:
            response = client.get('http://dashboard.example.com/get-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-dashboard-bundle' in str(body))
            self.assertTrue('dummy-dashboard-version' in str(body))

    def test_get_signup_bundle(self):
        # XXX Here we access the view by exposing it in a different path - the
        # production manner of distinguishing it (throught its subdomain) does
        # not work with the test client
        from eduid_webapp.jsconfig import views
        views.jsconfig_views.route('/get-signup-bundle', methods=['GET'])(views.get_signup_bundle)
        self.app.register_blueprint(views.jsconfig_views)
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn) as client:
            response = client.get('http://signup.example.com/get-signup-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-signup-bundle' in str(body))
            self.assertTrue('dummy-signup-version' in str(body))

    def test_get_login_bundle(self):
        # XXX Here we access the view by exposing it in a different path - the
        # production manner of distinguishing it (throught its subdomain) does
        # not work with the test client
        from eduid_webapp.jsconfig import views
        views.jsconfig_views.route('/get-login-bundle', methods=['GET'])(views.get_login_bundle)
        self.app.register_blueprint(views.jsconfig_views)
        eppn = self.test_user_data['eduPersonPrincipalName']
        with self.session_cookie(self.browser, eppn) as client:
            response = client.get('http://login.example.com/get-login-bundle')

            self.assertEqual(response.status_code, 200)

            body = response.data
            self.assertTrue('dummy-login-bundle' in str(body))
            self.assertTrue('dummy-login-version' in str(body))
<|endoftext|>


<commit_before>from OpenPNM.Utilities import misc
import scipy as _sp
import numpy as _np
import os as _os
import pickle as _pickle
from xml.etree import ElementTree as _ET

class PNM(object):

    def __init__(self,**kwargs):
        super().__init__(**kwargs)

    @staticmethod
    def save(network,filename=''):
        r'''
        Save the current simulation in it's entirity.

        Parameters
        ----------
        net : OpenPNM Network Object
            The network object of the simulation to be saved.  This will
            automatically save all Geometry, Phases and Physics objects
            associated with the Network, but will not save any Algorithms.

        filename : string, optional
            The file name to yse for saving.  Defaults to the Network's name.

        Notes
        -----
        This stores the simulation in a nested dictionary with the data dict
        of the object stored under ['data'][object.name], the object linking
        under ['tree'][object.name] and the information to reproduce the models
        under ['mods'][object.name].  The ``load`` method knows how to unpack
        this dictionary.

        Examples
        --------
        >>> # Saving
        >>> pn = OpenPNM.Network.Cubic(shape=[3,3,3])
        >>> geo = OpenPNM.Geometry.Stick_and_Ball(network=pn,pores=pn.pores(),throats=pn.throats(),name='geo_1')
        >>> air = OpenPNM.Phases.Air(network=pn)
        >>> phys = OpenPNM.Physics.Standard(network=pn,phase=air,pores=pn.pores(),throats=pn.throats())
        >>> import OpenPNM.Utilities.IO as io
        >>> io.PNM.save(pn,'test_pn')

        >>> # Loading
        >>> import OpenPNM.Utilities.IO as io
        >>> #pn = io.PNM.load('test_pn')

        >>> # Delete the new file
        >>> import os
        >>> os.remove('test_pn.pnm')

        See Also
        --------
        IO.PNM.load

        '''

        if filename != '':
            filename = filename.split('.')[0]
        else:
            filename = network.name

        #Setup nested dictionary to store simulation
        sim = {}

        #Collect all objects into a single list
        all_objs = [network]
        all_objs.extend(network._geometries)
        all_objs.extend(network._phases)
        all_objs.extend(network._physics)

        #Enter each object's data, object tree and models into dictionary
        for obj in all_objs:
#            try:
#                del obj._logger
#            except:
#                print('No logger found, ignoring request to delete it')
            sim[obj.name] = {}
            sim[obj.name]['data'] = obj.copy()
            sim[obj.name]['associations'] = {'Geometries' : obj.geometries(),
                                             'Phases'     : obj.phases(),
                                             'Physics'    : obj.physics()}
            sim[obj.name]['info'] = {'mro'   : [item.__name__ for item in obj.__class__.__mro__],
                                     'class' : obj.__class__}
            # Capture all of the objects attributes, other than OpenPNM reserved ones
            # Note: This could break if people store funky stuff in attributes
            excl_list = ['_physics','_geometries','_phases','_net','_name','_logger','_models']
            a = {key : obj.__dict__[key] for key in obj.__dict__.keys() if key not in excl_list}
            sim[obj.name]['attrs'] = a
            sim[obj.name]['models'] = {}
            for prop in list(obj._models.keys()):
                sim[obj.name]['models'][prop] = PNM._save_model(obj,prop)
        #Save nested dictionary pickle
        _pickle.dump(sim,open(filename+'.pnm','wb'))
#        #Save nested dictionary as a Numpy zip file
#        _sp.savez_compressed(filename,**sim)
#        #Rename the zip extension to pnm for kicks
#        try:
#            _os.remove(filename+'.pnm')
#        except:
#            pass
#        _os.rename(filename+'.npz',filename+'.pnm')

    @staticmethod
    def _save_model(obj,item):
        r'''
        '''
        #Retrieve info from model
        f = obj._models[item].func
        a = obj._models[item].keywords
        #Store path to model, name of model and argument key:value pairs in a dict
        model = {}
        model['func'] = f
        model['args'] = {}
        for item in a:
            #remove default arguments used in all add_model calls
            if item not in ['physics','network','phase','geometry','mixture']:
                model['args'][item] = a[item]
        return model

    @staticmethod
    def load(filename):
        r'''
        Load a saved simulation

        Parameters
        ----------
        filename : string
            The name of the simulation to be read in

        See Also
        --------
        IO.PNM.save

        '''
        #Read in file
        filename = filename.split('.')[0]
        sim = _pickle.load(open(filename+'.pnm','rb'))

        for name in sim.keys():  # Network object
            if 'GenericNetwork' in sim[name]['info']['mro']:
                obj = sim[name]
                net = obj['info']['class'](name=name)
                net.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(net,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(net,obj['models'][item])
                break

        for name in sim.keys():  # Geometry objects
            if 'GenericGeometry' in sim[name]['info']['mro']:
                obj = sim[name]
                Ps = net.pores(name)
                Ts = net.throats(name)
                geom = obj['info']['class'](network=net,pores=Ps,throats=Ts,name=name)
                geom.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(geom,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(geom,obj['models'][item])

        for name in sim.keys():  # Do Pure phases or independent mixtures first
            if 'GenericPhase' in sim[name]['info']['mro']:
                obj = sim[name]
                phase = obj['info']['class'](network=net,name=name)
                phase.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(phase,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(phase,obj['models'][item])

        for name in sim.keys():  # Physics objects
            if 'GenericPhysics' in sim[name]['info']['mro']:
                obj = sim[name]
                phase = net.phases(obj['associations']['Phases'])[0]  # This will always be only 1 phase
                Ps = net.pores(name)
                Ts = net.throats(name)
                phys = obj['info']['class'](network=net,phase=phase,name=name,pores=Ps,throats=Ts)
                phys.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(phys,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(phys,obj['models'][item])

        return net

    @staticmethod
    def _load_model(obj,model):
        r'''
        '''
        #Apply model to object using info in dict
        obj.add_model(model=model['func'],regen_mode='deferred',**model['args'])

class VTK():
    r"""
    Class for writing a Vtp file to be read by ParaView

    """

    _TEMPLATE = '''
    <?xml version="1.0" ?>
    <VTKFile byte_order="LittleEndian" type="PolyData" version="0.1">
        <PolyData>
            <Piece NumberOfLines="0" NumberOfPoints="0">
                <Points>
                </Points>
                <Lines>
                </Lines>
                <PointData>
                </PointData>
                <CellData>
                </CellData>
            </Piece>
        </PolyData>
    </VTKFile>
    '''.strip()

    def __init__(self,**kwargs):
        r"""
        Initialize
        """
        super().__init__(**kwargs)

    @staticmethod
    def save(network,filename='',phases=[]):
        r'''
        Save network and phase data to a single vtp file for visualizing in
        Paraview

        Parameters
        ----------
        network : OpenPNM Network Object
            The Network containing the data to be written

        filename : string, optional
            Filename to write data.  If no name is given the file is named after
            ther network

        phases : list, optional
            A list contain OpenPNM Phase object(s) containing data to be written

        Examples
        --------
        >>> pn = OpenPNM.Network.Cubic(shape=[3,3,3])
        >>> geo = OpenPNM.Geometry.Stick_and_Ball(network=pn,pores=pn.pores(),throats=pn.throats(),name='geo_1')
        >>> air = OpenPNM.Phases.Air(network=pn)
        >>> phys = OpenPNM.Physics.Standard(network=pn,phase=air,pores=pn.pores(),throats=pn.throats())

        >>> import OpenPNM.Utilities.IO as io
        >>> io.VTK.save(pn,'test_pn.vtp',[air])

        >>> # Delete the new file
        >>> import os
        >>> os.remove('test_pn.vtp')
        '''

        if filename == '':
            filename = network.name+'.vtp'

        root = _ET.fromstring(VTK._TEMPLATE)
        objs = []
        if type(phases) != list:
            phases = [phases]
        for phase in phases:
            objs.append(phase)
        objs.append(network)
        am = misc.amalgamate_data(objs=objs)
        key_list = list(sorted(am.keys()))
        points = network['pore.coords']
        pairs = network['throat.conns']

        num_points = len(points)
        num_throats = len(pairs)

        piece_node = root.find('PolyData').find('Piece')
        piece_node.set("NumberOfPoints", str(num_points))
        piece_node.set("NumberOfLines", str(num_throats))

        points_node = piece_node.find('Points')
        coords = VTK._array_to_element("coords", points.T.ravel('F'), n=3)
        points_node.append(coords)

        lines_node = piece_node.find('Lines')
        connectivity = VTK._array_to_element("connectivity", pairs)
        lines_node.append(connectivity)
        offsets = VTK._array_to_element("offsets", 2*_np.arange(len(pairs))+2)
        lines_node.append(offsets)

        point_data_node = piece_node.find('PointData')
        for key in key_list:
            array = am[key]
            if array.dtype == _np.bool: array = array.astype(int)
            if array.size != num_points: continue
            element = VTK._array_to_element(key, array)
            point_data_node.append(element)

        cell_data_node = piece_node.find('CellData')
        for key in key_list:
            array = am[key]
            if array.dtype == _np.bool: array = array.astype(int)
            if array.size != num_throats: continue
            element = VTK._array_to_element(key, array)
            cell_data_node.append(element)

        tree = _ET.ElementTree(root)
        tree.write(filename)

        #Make pretty
        with open(filename, "r+") as f:
            string = f.read()
            string = string.replace("</DataArray>", "</DataArray>\n\t\t\t")
            f.seek(0)
            # consider adding header: '<?xml version="1.0"?>\n'+
            f.write(string)

    @staticmethod
    def load(filename):
        r'''
        Read in pore and throat data from a saved VTK file.

        Notes
        -----
        This will NOT reproduce original simulation, since all models and object
        relationships are lost.  Use IO.Save and IO.Load for that.'''
        network = OpenPNM.Network.GenericNetwork()
        tree = _ET.parse(filename)
        piece_node = tree.find('PolyData').find('Piece')

        # extract connectivity
        conn_element = piece_node.find('Lines').find('DataArray')
        array = VTK._element_to_array(conn_element, 2)
        network['throat.conns'] = array.T

        for element in piece_node.find('PointData').iter('DataArray'):
            key = element.get('Name')
            array = VTK._element_to_array(element)
            netname = key.split('.')[0]
            propname = key.strip(netname+'.')
            network[propname] = array

        return network

    @staticmethod
    def _array_to_element(name, array, n=1):
        dtype_map = {
            'int8'   : 'Int8',
            'int16'  : 'Int16',
            'int32'  : 'Int32',
            'int64'  : 'Int64',
            'uint8'  : 'UInt8',
            'uint16' : 'UInt16',
            'uint32' : 'UInt32',
            'uint64' : 'UInt64',
            'float32': 'Float32',
            'float64': 'Float64',
            'str'    : 'String',
        }
        element = _ET.Element('DataArray')
        element.set("Name", name)
        element.set("NumberOfComponents", str(n))
        element.set("type", dtype_map[str(array.dtype)])
        element.text = '\t'.join(map(str,array.ravel()))
        return element

    @staticmethod
    def _element_to_array(element, n=1):
        string = element.text
        dtype = element.get("type")
        array = _np.fromstring(string, sep='\t')
        array = array.astype(dtype)
        if n is not 1:
            array = array.reshape(array.size//n, n)
        return array

class MAT():
    r'''
    Class for reading and writing OpenPNM data to a Matlab 'mat' file
    '''

    def __init__(self,**kwargs):
        r"""
        Initialize
        """
        super().__init__(**kwargs)

    @staticmethod
    def save(network, filename='', phases=[]):
        r"""
        Write Network to a Mat file for exporting to Matlab. This method will be
        enhanced in a future update, and it's functionality may change!

        Parameters
        ----------

        network : OpenPNM Network Object

        filename : string
            Desired file name, defaults to network name if not given

        phases : list of phase objects ([])
            Phases that have properties we want to write to file

        Examples
        --------
        >>> pn = OpenPNM.Network.TestNet()
        >>> geo = OpenPNM.Geometry.TestGeometry(network=pn,pores=pn.pores(),throats=pn.throats())
        >>> air = OpenPNM.Phases.TestPhase()
        >>> import OpenPNM.Utilities.IO as io
        >>> io.MAT.save(network=pn,filename='test_pn.mat',phases=air)

        >>> #Remove newly created file
        >>> import os
        >>> os.remove('test_pn.mat')

        """
        if filename == '':
            filename = network.name+'.mat'
        pnMatlab = {}
        new = []
        old = []
        for keys in network.keys():
            old.append(keys)
            new.append(keys.replace('.','_'))

        for i in range(len(network)):
            pnMatlab[new[i]] = network[old[i]]

        if type(phases) != list:
            phases = [phases]
        if len(phases) != 0:
            for j in range(len(phases)):
                new = []
                old = []

                for keys in phases[j].keys():
                    old.append(keys)
                    new.append(phases[j].name+'_'+keys.replace('.','_'))

                for i in range(len(phases[j])):
                    pnMatlab[new[i]] = phases[j][old[i]]

        _sp.io.savemat(file_name=filename,mdict=pnMatlab)

    @staticmethod
    def load():
        r'''
        This method is not implemented yet.
        '''
        raise NotImplemented()

if __name__ == '__main__':
    import doctest
    doctest.testmod(verbose=True)

<commit_msg>PNM.save/load now works with mixtures - The root of all our problems is the object linking - This means that objects must be re-initialized in the correct order and all kinds of tricks must be taken to recreate the linkages. - There must be a better way! - I'm hoping that the 'simulation controller' object will solve the problems, but this is a longer term aim now. I want to think about it and consider it carefully.<commit_after>from OpenPNM.Utilities import misc
import scipy as _sp
import numpy as _np
import os as _os
import pickle as _pickle
from xml.etree import ElementTree as _ET

class PNM(object):

    def __init__(self,**kwargs):
        super().__init__(**kwargs)

    @staticmethod
    def save(network,filename=''):
        r'''
        Save the current simulation in it's entirity.

        Parameters
        ----------
        net : OpenPNM Network Object
            The network object of the simulation to be saved.  This will
            automatically save all Geometry, Phases and Physics objects
            associated with the Network, but will not save any Algorithms.

        filename : string, optional
            The file name to yse for saving.  Defaults to the Network's name.

        Notes
        -----
        This stores the simulation in a nested dictionary with the data dict
        of the object stored under ['data'][object.name], the object linking
        under ['tree'][object.name] and the information to reproduce the models
        under ['mods'][object.name].  The ``load`` method knows how to unpack
        this dictionary.

        Examples
        --------
        >>> # Saving
        >>> pn = OpenPNM.Network.Cubic(shape=[3,3,3])
        >>> geo = OpenPNM.Geometry.Stick_and_Ball(network=pn,pores=pn.pores(),throats=pn.throats(),name='geo_1')
        >>> air = OpenPNM.Phases.Air(network=pn)
        >>> phys = OpenPNM.Physics.Standard(network=pn,phase=air,pores=pn.pores(),throats=pn.throats())
        >>> import OpenPNM.Utilities.IO as io
        >>> io.PNM.save(pn,'test_pn')

        >>> # Loading
        >>> import OpenPNM.Utilities.IO as io
        >>> #pn = io.PNM.load('test_pn')

        >>> # Delete the new file
        >>> import os
        >>> os.remove('test_pn.pnm')

        See Also
        --------
        IO.PNM.load

        '''

        if filename != '':
            filename = filename.split('.')[0]
        else:
            filename = network.name

        #Setup nested dictionary to store simulation
        sim = {}

        #Collect all objects into a single list
        all_objs = [network]
        all_objs.extend(network._geometries)
        all_objs.extend(network._phases)
        all_objs.extend(network._physics)

        #Enter each object's data, object tree and models into dictionary
        for obj in all_objs:
#            try:
#                del obj._logger
#            except:
#                print('No logger found, ignoring request to delete it')
            sim[obj.name] = {}
            sim[obj.name]['data'] = obj.copy()
            sim[obj.name]['associations'] = {'Geometries' : obj.geometries(),
                                             'Phases'     : obj.phases(),
                                             'Physics'    : obj.physics()}
            sim[obj.name]['info'] = {'mro'   : [item.__name__ for item in obj.__class__.__mro__],
                                     'class' : obj.__class__}
            # Capture all of the objects attributes, other than OpenPNM reserved ones
            # Note: This could break if people store funky stuff in attributes
            excl_list = ['_physics','_geometries','_phases','_net','_name','_logger','_models']
            a = {key : obj.__dict__[key] for key in obj.__dict__.keys() if key not in excl_list}
            sim[obj.name]['attrs'] = a
            sim[obj.name]['models'] = {}
            for prop in list(obj._models.keys()):
                sim[obj.name]['models'][prop] = PNM._save_model(obj,prop)
        #Save nested dictionary pickle
        _pickle.dump(sim,open(filename+'.pnm','wb'))
#        #Save nested dictionary as a Numpy zip file
#        _sp.savez_compressed(filename,**sim)
#        #Rename the zip extension to pnm for kicks
#        try:
#            _os.remove(filename+'.pnm')
#        except:
#            pass
#        _os.rename(filename+'.npz',filename+'.pnm')

    @staticmethod
    def _save_model(obj,item):
        r'''
        '''
        #Retrieve info from model
        f = obj._models[item].func
        a = obj._models[item].keywords
        #Store path to model, name of model and argument key:value pairs in a dict
        model = {}
        model['func'] = f
        model['args'] = {}
        for item in a:
            #remove default arguments used in all add_model calls
            if item not in ['physics','network','phase','geometry','mixture']:
                model['args'][item] = a[item]
        return model

    @staticmethod
    def load(filename):
        r'''
        Load a saved simulation

        Parameters
        ----------
        filename : string
            The name of the simulation to be read in

        See Also
        --------
        IO.PNM.save

        '''
        #Read in file
        filename = filename.split('.')[0]
        sim = _pickle.load(open(filename+'.pnm','rb'))

        for name in sim.keys():  # Network object
            if 'GenericNetwork' in sim[name]['info']['mro']:
                obj = sim[name]
                net = obj['info']['class'](name=name)
                net.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(net,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(net,obj['models'][item])
                break

        for name in sim.keys():  # Geometry objects
            if 'GenericGeometry' in sim[name]['info']['mro']:
                obj = sim[name]
                Ps = net.pores(name)
                Ts = net.throats(name)
                geom = obj['info']['class'](network=net,pores=Ps,throats=Ts,name=name)
                geom.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(geom,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(geom,obj['models'][item])

        for name in sim.keys():  # Do Pure phases or independent mixtures first
            if 'GenericPhase' in sim[name]['info']['mro']:
                obj = sim[name]
                phase = obj['info']['class'](network=net,name=name)
                phase.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(phase,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(phase,obj['models'][item])

        for name in sim.keys():  # Link the phase objects to each other
            if 'GenericPhase' in sim[name]['info']['mro']:
                phase = net.phases(name)[0]
                phase._phases = net.phases(sim[name]['associations']['Phases'])

        for name in sim.keys():  # Physics objects
            if 'GenericPhysics' in sim[name]['info']['mro']:
                obj = sim[name]
                phase = net.phases(obj['associations']['Phases'])[0]  # This will always be only 1 phase
                Ps = net.pores(name)
                Ts = net.throats(name)
                phys = obj['info']['class'](network=net,phase=phase,name=name,pores=Ps,throats=Ts)
                phys.update(obj['data'])
                for item in obj['attrs'].keys():
                    setattr(phys,item,obj['attrs'][item])
                for item in obj['models'].keys():
                    PNM._load_model(phys,obj['models'][item])

        return net

    @staticmethod
    def _load_model(obj,model):
        r'''
        '''
        #Apply model to object using info in dict
        obj.add_model(model=model['func'],regen_mode='deferred',**model['args'])

class VTK():
    r"""
    Class for writing a Vtp file to be read by ParaView

    """

    _TEMPLATE = '''
    <?xml version="1.0" ?>
    <VTKFile byte_order="LittleEndian" type="PolyData" version="0.1">
        <PolyData>
            <Piece NumberOfLines="0" NumberOfPoints="0">
                <Points>
                </Points>
                <Lines>
                </Lines>
                <PointData>
                </PointData>
                <CellData>
                </CellData>
            </Piece>
        </PolyData>
    </VTKFile>
    '''.strip()

    def __init__(self,**kwargs):
        r"""
        Initialize
        """
        super().__init__(**kwargs)

    @staticmethod
    def save(network,filename='',phases=[]):
        r'''
        Save network and phase data to a single vtp file for visualizing in
        Paraview

        Parameters
        ----------
        network : OpenPNM Network Object
            The Network containing the data to be written

        filename : string, optional
            Filename to write data.  If no name is given the file is named after
            ther network

        phases : list, optional
            A list contain OpenPNM Phase object(s) containing data to be written

        Examples
        --------
        >>> pn = OpenPNM.Network.Cubic(shape=[3,3,3])
        >>> geo = OpenPNM.Geometry.Stick_and_Ball(network=pn,pores=pn.pores(),throats=pn.throats(),name='geo_1')
        >>> air = OpenPNM.Phases.Air(network=pn)
        >>> phys = OpenPNM.Physics.Standard(network=pn,phase=air,pores=pn.pores(),throats=pn.throats())

        >>> import OpenPNM.Utilities.IO as io
        >>> io.VTK.save(pn,'test_pn.vtp',[air])

        >>> # Delete the new file
        >>> import os
        >>> os.remove('test_pn.vtp')
        '''

        if filename == '':
            filename = network.name+'.vtp'

        root = _ET.fromstring(VTK._TEMPLATE)
        objs = []
        if type(phases) != list:
            phases = [phases]
        for phase in phases:
            objs.append(phase)
        objs.append(network)
        am = misc.amalgamate_data(objs=objs)
        key_list = list(sorted(am.keys()))
        points = network['pore.coords']
        pairs = network['throat.conns']

        num_points = len(points)
        num_throats = len(pairs)

        piece_node = root.find('PolyData').find('Piece')
        piece_node.set("NumberOfPoints", str(num_points))
        piece_node.set("NumberOfLines", str(num_throats))

        points_node = piece_node.find('Points')
        coords = VTK._array_to_element("coords", points.T.ravel('F'), n=3)
        points_node.append(coords)

        lines_node = piece_node.find('Lines')
        connectivity = VTK._array_to_element("connectivity", pairs)
        lines_node.append(connectivity)
        offsets = VTK._array_to_element("offsets", 2*_np.arange(len(pairs))+2)
        lines_node.append(offsets)

        point_data_node = piece_node.find('PointData')
        for key in key_list:
            array = am[key]
            if array.dtype == _np.bool: array = array.astype(int)
            if array.size != num_points: continue
            element = VTK._array_to_element(key, array)
            point_data_node.append(element)

        cell_data_node = piece_node.find('CellData')
        for key in key_list:
            array = am[key]
            if array.dtype == _np.bool: array = array.astype(int)
            if array.size != num_throats: continue
            element = VTK._array_to_element(key, array)
            cell_data_node.append(element)

        tree = _ET.ElementTree(root)
        tree.write(filename)

        #Make pretty
        with open(filename, "r+") as f:
            string = f.read()
            string = string.replace("</DataArray>", "</DataArray>\n\t\t\t")
            f.seek(0)
            # consider adding header: '<?xml version="1.0"?>\n'+
            f.write(string)

    @staticmethod
    def load(filename):
        r'''
        Read in pore and throat data from a saved VTK file.

        Notes
        -----
        This will NOT reproduce original simulation, since all models and object
        relationships are lost.  Use IO.Save and IO.Load for that.'''
        network = OpenPNM.Network.GenericNetwork()
        tree = _ET.parse(filename)
        piece_node = tree.find('PolyData').find('Piece')

        # extract connectivity
        conn_element = piece_node.find('Lines').find('DataArray')
        array = VTK._element_to_array(conn_element, 2)
        network['throat.conns'] = array.T

        for element in piece_node.find('PointData').iter('DataArray'):
            key = element.get('Name')
            array = VTK._element_to_array(element)
            netname = key.split('.')[0]
            propname = key.strip(netname+'.')
            network[propname] = array

        return network

    @staticmethod
    def _array_to_element(name, array, n=1):
        dtype_map = {
            'int8'   : 'Int8',
            'int16'  : 'Int16',
            'int32'  : 'Int32',
            'int64'  : 'Int64',
            'uint8'  : 'UInt8',
            'uint16' : 'UInt16',
            'uint32' : 'UInt32',
            'uint64' : 'UInt64',
            'float32': 'Float32',
            'float64': 'Float64',
            'str'    : 'String',
        }
        element = _ET.Element('DataArray')
        element.set("Name", name)
        element.set("NumberOfComponents", str(n))
        element.set("type", dtype_map[str(array.dtype)])
        element.text = '\t'.join(map(str,array.ravel()))
        return element

    @staticmethod
    def _element_to_array(element, n=1):
        string = element.text
        dtype = element.get("type")
        array = _np.fromstring(string, sep='\t')
        array = array.astype(dtype)
        if n is not 1:
            array = array.reshape(array.size//n, n)
        return array

class MAT():
    r'''
    Class for reading and writing OpenPNM data to a Matlab 'mat' file
    '''

    def __init__(self,**kwargs):
        r"""
        Initialize
        """
        super().__init__(**kwargs)

    @staticmethod
    def save(network, filename='', phases=[]):
        r"""
        Write Network to a Mat file for exporting to Matlab. This method will be
        enhanced in a future update, and it's functionality may change!

        Parameters
        ----------

        network : OpenPNM Network Object

        filename : string
            Desired file name, defaults to network name if not given

        phases : list of phase objects ([])
            Phases that have properties we want to write to file

        Examples
        --------
        >>> pn = OpenPNM.Network.TestNet()
        >>> geo = OpenPNM.Geometry.TestGeometry(network=pn,pores=pn.pores(),throats=pn.throats())
        >>> air = OpenPNM.Phases.TestPhase()
        >>> import OpenPNM.Utilities.IO as io
        >>> io.MAT.save(network=pn,filename='test_pn.mat',phases=air)

        >>> #Remove newly created file
        >>> import os
        >>> os.remove('test_pn.mat')

        """
        if filename == '':
            filename = network.name+'.mat'
        pnMatlab = {}
        new = []
        old = []
        for keys in network.keys():
            old.append(keys)
            new.append(keys.replace('.','_'))

        for i in range(len(network)):
            pnMatlab[new[i]] = network[old[i]]

        if type(phases) != list:
            phases = [phases]
        if len(phases) != 0:
            for j in range(len(phases)):
                new = []
                old = []

                for keys in phases[j].keys():
                    old.append(keys)
                    new.append(phases[j].name+'_'+keys.replace('.','_'))

                for i in range(len(phases[j])):
                    pnMatlab[new[i]] = phases[j][old[i]]

        _sp.io.savemat(file_name=filename,mdict=pnMatlab)

    @staticmethod
    def load():
        r'''
        This method is not implemented yet.
        '''
        raise NotImplemented()

if __name__ == '__main__':
    import doctest
    doctest.testmod(verbose=True)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from marshmallow import Schema, fields
from eduid_common.api.schemas.base import FluxStandardAction
from eduid_common.api.schemas.validators import validate_nin

__author__ = 'lundberg'

class LetterProofingRequestSchema(Schema):

    class Meta:
        strict = True

    nin = fields.String(required=False, validate=validate_nin, missing=None)

class VerifyCodeRequestSchema(Schema):

    class Meta:
        strict = True

    verification_code = fields.String(required=True)

class LetterProofingResponseSchema(FluxStandardAction):

    class LetterProofingPayload(Schema):
        letter_sent = fields.DateTime(format='%s')
        letter_expires = fields.DateTime(format='%s')
        letter_expired = fields.Boolean()

    payload = fields.Nested(LetterProofingPayload)

class VerifyCodeResponseSchema(FluxStandardAction):

    class VerifyCodePayload(Schema):
        success = fields.Boolean(required=True)
        message = fields.String(required=False)

    payload = fields.Nested(VerifyCodePayload)

class LetterProofingDataSchema(Schema):

    class Meta:
        strict = True

    number = fields.String(required=True)
    created_by = fields.String(required=True)
    created_ts = fields.DateTime(required=True, format='%s')
    verified = fields.Boolean(required=True)
    verified_by = fields.String(required=True)
    verified_ts = fields.DateTime(required=True, format='%s')
    verification_code = fields.String(required=True)
    official_address = fields.Dict(required=True)
    transaction_id = fields.String(required=True)<commit_msg>Start from EduidSchema instead of Schema<commit_after># -*- coding: utf-8 -*-

from marshmallow import fields
from eduid_common.api.schemas.base import EduidSchema, FluxStandardAction
from eduid_common.api.schemas.validators import validate_nin

__author__ = 'lundberg'

class LetterProofingRequestSchema(EduidSchema):

    nin = fields.String(required=True, validate=validate_nin)

class VerifyCodeRequestSchema(EduidSchema):

    verification_code = fields.String(required=True)

class LetterProofingResponseSchema(FluxStandardAction):

    class Meta:
        strict = True

    class LetterProofingPayload(EduidSchema):
        letter_sent = fields.DateTime(format='%s')
        letter_expires = fields.DateTime(format='%s')
        letter_expired = fields.Boolean()

    payload = fields.Nested(LetterProofingPayload)

class VerifyCodeResponseSchema(FluxStandardAction):

    class VerifyCodePayload(EduidSchema):
        success = fields.Boolean(required=True)
        message = fields.String(required=False)

    payload = fields.Nested(VerifyCodePayload)

class LetterProofingDataSchema(EduidSchema):

    number = fields.String(required=True)
    created_by = fields.String(required=True)
    created_ts = fields.DateTime(required=True, format='%s')
    verified = fields.Boolean(required=True)
    verified_by = fields.String(required=True)
    verified_ts = fields.DateTime(required=True, format='%s')
    verification_code = fields.String(required=True)
    official_address = fields.Dict(required=True)
    transaction_id = fields.String(required=True)<|endoftext|>


<commit_before>import pytest

import plotly.graph_objs as go
import numpy as np

import sisl

pytestmark = [pytest.mark.viz, pytest.mark.plotly]

@pytest.fixture
def setup():
    t = sisl.utils.PropertyDict()
    r = np.linspace(0, 3.5, 50)
    f = np.exp(-r)
    t.orb = sisl.AtomicOrbital('2pzZ', (r, f))
    t.geom = (sisl.geom
              .graphene(orthogonal=True, atoms=sisl.Atom(6, t.orb))
              .move([0, 0, 5]))
    t.H = sisl.Hamiltonian(t.geom)
    t.H.construct([(0.1, 1.44), (0, -2.7)], )
    return t

def test_eigenstate_wf(setup):

    H = setup.H
    geometry = H.geometry

    plot = H.eigenstate()[0].plot.wavefunction(geometry=geometry)

    assert len(plot.data) > 0
    assert isinstance(plot.data[0], go.Isosurface)

def test_hamiltonian_wf(setup):
    H = setup.H
    geometry = H.geometry

    # Check if it works for 3D plots
    plot = H.plot.wavefunction(2)
    assert isinstance(plot.data[0], go.Isosurface)

    # Check that setting plot geom to True adds data traces
    plot.update_settings(plot_geom=False)
    prev_len = len(plot.data)
    plot.update_settings(plot_geom=True)
    assert len(plot.data) > prev_len

    # Now 2D
    plot = H.plot.wavefunction(2, axes=[0, 1])
    assert isinstance(plot.data[0], go.Heatmap)

    # Check that setting plot geom to True adds data traces
    plot.update_settings(plot_geom=False)
    prev_len = len(plot.data)
    plot.update_settings(plot_geom=True)
    assert len(plot.data) > prev_len
<commit_msg>maint: removed plotables tests<commit_after><|endoftext|>


<commit_before># -*- coding: utf8 -*-

import json
from rq import Queue
from redis import Redis
from flask import Blueprint, request, current_app, jsonify, abort
from libcrowds_analyst import analysis

BP = Blueprint('api', __name__)
QUEUE = Queue('libcrowds_analyst', connection=Redis())
MINUTE = 60

def analyse(func):
    """Analyse a webhook."""
    if request.method == 'POST' and payload['event'] != 'task_completed':
        abort(400)
    elif request.method == 'POST' and payload['event'] == 'task_completed':
        payload = json.loads(request.json) or {}
        payload['api_key'] = current_app.config['API_KEY']
        payload['endpoint'] = current_app.config['ENDPOINT']
        payload['doi'] = current_app.config['DOI']
        QUEUE.enqueue_call(func=func, kwargs=payload, timeout=10*MINUTE)
    response = jsonify({
        "message": "OK",
        "status": 200
    })
    response.status_code = 200
    return response

@BP.route('convert-a-card', methods=['GET', 'POST'])
def convert_a_card():
    """Endpoint for Convert-a-Card webhooks."""
    return analyse(analysis.convert_a_card.analyse)

@BP.route('playbills/select', methods=['GET', 'POST'])
def playbills_mark():
    """Endpoint for In the Spotlight select task webhooks."""
    return analyse(analysis.playbills.analyse_selections)
<commit_msg>Fix API analyse<commit_after># -*- coding: utf8 -*-

import json
from rq import Queue
from redis import Redis
from flask import Blueprint, request, current_app, jsonify, abort
from libcrowds_analyst import analysis

BP = Blueprint('api', __name__)
QUEUE = Queue('libcrowds_analyst', connection=Redis())
MINUTE = 60

def analyse(func):
    """Analyse a webhook."""
    payload = json.loads(request.json) or {}
    if request.method == 'POST' and payload['event'] != 'task_completed':
        abort(400)
    elif request.method == 'POST' and payload['event'] == 'task_completed':
        payload['api_key'] = current_app.config['API_KEY']
        payload['endpoint'] = current_app.config['ENDPOINT']
        payload['doi'] = current_app.config['DOI']
        QUEUE.enqueue_call(func=func, kwargs=payload, timeout=10*MINUTE)
    response = jsonify({
        "message": "OK",
        "status": 200
    })
    response.status_code = 200
    return response

@BP.route('convert-a-card', methods=['GET', 'POST'])
def convert_a_card():
    """Endpoint for Convert-a-Card webhooks."""
    return analyse(analysis.convert_a_card.analyse)

@BP.route('playbills/select', methods=['GET', 'POST'])
def playbills_mark():
    """Endpoint for In the Spotlight select task webhooks."""
    return analyse(analysis.playbills.analyse_selections)
<|endoftext|>


<commit_before># Copyright (c) 2014 Eric Youngson

# This file is part of eppy.

# Eppy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# Eppy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with eppy.  If not, see <http://www.gnu.org/licenses/>.

"""This module is used to implement native Python functions to replace those
    called from numpy, when using eppy with Rhino"""
# Written by Eric Youngson eric@successionecological.com / eayoungs@gmail.com
# Succession Ecological Services: Portland, Oregon

# Exception class
class LinAlgError(Exception):
    """
    Generic Python-exception-derived object raised by linalg functions.

    General purpose exception class, derived from Python's exception.Exception
    class, programmatically raised in linalg functions when a Linear
    Algebra-related condition would prevent further correct execution of the
    function.

    Parameters
    ----------
    None

    Examples
    --------
    >>> from numpy import linalg as LA
    >>> LA.inv(np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "...linalg.py", line 350,
        in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
      File "...linalg.py", line 249,
        in solve
        raise LinAlgError('Singular matrix')
    numpy.linalg.LinAlgError: Singular matrix

    """
    pass

# Dealing with errors in _umath_linalg

_linalg_error_extobj = None

def _raise_linalgerror_singular(err, flag):
    raise LinAlgError("Singular matrix")

def vctr_cross(u, v):
    """
    Return the cross product of two 3 dimentional vectors.

    The cross product of `u` and `v` in :math:`R^3` is a vector perpendicular
    to both `u` and `v`.  If `u` and `v` are arrays of vectors, the vectors
    are defined by the last axis of `u` and `v` by default, and these axes
    can have dimensions 2 or 3.

    Parameters
    ----------
    u : array_like
        Components of the first vector(s).
    v : array_like
        Components of the second vector(s).

    Returns
    -------
    uxv : 3darray
        Vector cross product(s).

    Raises
    ------
    ValueError
        When the dimension of the vector(s) in `u` and/or `v` does not
        equal 3.

    Examples
    --------
    Vector cross-product.

    >>> x = [1, 2, 3]
    >>> y = [4, 5, 6]
    >>> np.cross(x, y)
    array([-3,  6, -3])
    """

    uDim = len(u)
    vDim = len(v)

    uxv = []

    # http://mathworld.wolfram.com/CrossProduct.html
    if uDim == vDim == 3:
        for i in range(uDim):
            uxv.append(0)
        uxv = [u[1]*v[2]-u[2]*v[1],
               -(u[0]*v[2]-u[2]*v[0]),
               u[0]*v[1]-u[1]*v[0]]
    else:
            uxv = 'ERROR'
    return uxv

def vctr_dot(u, v):
    """
    Return the dot product of two 3 dimentional vectors.

    The dot product of `u` and `v` in :math:`R^3` is a vector perpendicular
    to both `u` and `v`.  If `u` and `v` are arrays of vectors, the vectors
    are defined by the last axis of `u` and `v` by default, and these axes
    can have dimensions 2 or 3.

    Parameters
    ----------
    u : array_like
        Components of the first vector(s).
    v : array_like
        Components of the second vector(s).

    Returns
    -------
    uxv : 3darray
        Vector dot product(s).

    Raises
    ------
    ValueError
        When the dimension of the vector(s) in `u` and/or `v` does not
        equal 3.

    Examples
    --------
    Vector dot-product.

    >>> x = [1, 2, 3]
    >>> y = [4, 5, 6]
    >>> np.dot(x, y)
    array([4, 10, 18])
    """

    uDim = len(u)
    vDim = len(v)

    u_dot_v = []

    # http://reference.wolfram.com/language/ref/Dot.html
    if uDim == vDim == 3:
        for i in range(uDim):
            u_dot_v.append(0)
        u_dot_v = [u[0]*v[0],
                   u[1]*v[1],
                   u[2]*v[2]]
    else:
            u_dot_v = 'ERROR'
    return u_dot_v

def vctr_det(u, v, w):
    uDim = len(u)
    vDim = len(v)
    wDim = len(w)

    det_A = []

    if uDim == vDim == wDim == 3:
        A = [[u[0], u[1], u[2]], [v[0], v[1], v[2]], [w[0], w[1], w[2]]]
        det_A = A[0][0] * A[1][1] * A[2][2] + A[0][1] * A[1][2] * A[2][0] \
                + A[0][2] * A[1][0] * A[2][1] - (A[0][2] * A[1][1] * A[2][0]
                + A[0][1] * A[1][0] * A[2][2] + A[0][0] * A[1][2] * A[2][1])
    return det_A
<commit_msg>Branch: i30_pythongeometry | Intent: Create module of native Python functions to 	replace numpy functions used in eppy geometry modules Commit Intent: Add a simple exception from Numpy's linalg module to get a working 	exception --------------------------------------------------------------------------------------- *eppy/geometry/py_numeric.py* -Added a try statement to the vctr_det function to use singlar matrix exception... -Indented the return statement after the else clause... -Attempted to adjust line length for pep8: Still fails(?)<commit_after># Copyright (c) 2014 Eric Youngson

# This file is part of eppy.

# Eppy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# Eppy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with eppy.  If not, see <http://www.gnu.org/licenses/>.

"""This module is used to implement native Python functions to replace those
    called from numpy, when using eppy with Rhino"""
# Written by Eric Youngson eric@successionecological.com / eayoungs@gmail.com
# Succession Ecological Services: Portland, Oregon

# Exception class
class LinAlgError(Exception):
    """
    Generic Python-exception-derived object raised by linalg functions.

    General purpose exception class, derived from Python's exception.Exception
    class, programmatically raised in linalg functions when a Linear
    Algebra-related condition would prevent further correct execution of the
    function.

    Parameters
    ----------
    None

    Examples
    --------
    >>> from numpy import linalg as LA
    >>> LA.inv(np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "...linalg.py", line 350,
        in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
      File "...linalg.py", line 249,
        in solve
        raise LinAlgError('Singular matrix')
    numpy.linalg.LinAlgError: Singular matrix

    """
    pass

# Dealing with errors in _umath_linalg

_linalg_error_extobj = None

def _raise_linalgerror_singular(err, flag):
    raise LinAlgError("Singular matrix")

def vctr_cross(u, v):
    """
    Return the cross product of two 3 dimentional vectors.

    The cross product of `u` and `v` in :math:`R^3` is a vector perpendicular
    to both `u` and `v`.  If `u` and `v` are arrays of vectors, the vectors
    are defined by the last axis of `u` and `v` by default, and these axes
    can have dimensions 2 or 3.

    Parameters
    ----------
    u : array_like
        Components of the first vector(s).
    v : array_like
        Components of the second vector(s).

    Returns
    -------
    uxv : 3darray
        Vector cross product(s).

    Raises
    ------
    ValueError
        When the dimension of the vector(s) in `u` and/or `v` does not
        equal 3.

    Examples
    --------
    Vector cross-product.

    >>> x = [1, 2, 3]
    >>> y = [4, 5, 6]
    >>> np.cross(x, y)
    array([-3,  6, -3])
    """

    uDim = len(u)
    vDim = len(v)

    uxv = []

    # http://mathworld.wolfram.com/CrossProduct.html
    if uDim == vDim == 3:
        for i in range(uDim):
            uxv.append(0)
        uxv = [u[1]*v[2]-u[2]*v[1],
               -(u[0]*v[2]-u[2]*v[0]),
               u[0]*v[1]-u[1]*v[0]]
    else:
            uxv = 'ERROR'
    return uxv

def vctr_dot(u, v):
    """
    Return the dot product of two 3 dimentional vectors.

    The dot product of `u` and `v` in :math:`R^3` is a vector perpendicular
    to both `u` and `v`.  If `u` and `v` are arrays of vectors, the vectors
    are defined by the last axis of `u` and `v` by default, and these axes
    can have dimensions 2 or 3.

    Parameters
    ----------
    u : array_like
        Components of the first vector(s).
    v : array_like
        Components of the second vector(s).

    Returns
    -------
    uxv : 3darray
        Vector dot product(s).

    Raises
    ------
    ValueError
        When the dimension of the vector(s) in `u` and/or `v` does not
        equal 3.

    Examples
    --------
    Vector dot-product.

    >>> x = [1, 2, 3]
    >>> y = [4, 5, 6]
    >>> np.dot(x, y)
    array([4, 10, 18])
    """

    uDim = len(u)
    vDim = len(v)

    u_dot_v = []

    # http://reference.wolfram.com/language/ref/Dot.html
    if uDim == vDim == 3:
        for i in range(uDim):
            u_dot_v.append(0)
        u_dot_v = [u[0]*v[0],
                   u[1]*v[1],
                   u[2]*v[2]]
    else:
            u_dot_v = 'ERROR'
    return u_dot_v

def vctr_det(u, v, w):
    uDim = len(u)
    vDim = len(v)
    wDim = len(w)

    det_A = []

    if uDim == vDim == wDim == 3:
        try:
            A = [[u[0], u[1], u[2]], [v[0], v[1], v[2]], [w[0], w[1], w[2]]]
            det_A = (A[0][0] * A[1][1] * A[2][2] + A[0][1] * A[1][2] * A[2][0]
                + A[0][2] * A[1][0] * A[2][1] - (A[0][2] * A[1][1] * A[2][0]
                + A[0][1] * A[1][0] * A[2][2] + A[0][0] * A[1][2]
                * A[2][1])
                )
        except _raise_linalgerror_singular:
            print("ERROR: Singluar Matrix")
        else:
            return det_A
<|endoftext|>


<commit_before>__version_tuple__ = (1, 0, 0, 'beta', 6)
__version__ = '1.0.0-beta.6'
<commit_msg>Release 1.0.0-beta+7<commit_after>__version_tuple__ = (1, 0, 0, 'beta', '7')
__version__ = '1.0.0-beta+7'
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from __future__ import print_function, absolute_import, unicode_literals

import struct
import json
import base64
from flask import Blueprint, session, Response
from flask import current_app, request

from fido2.client import ClientData
from fido2.server import Fido2Server, RelyingParty
from fido2.ctap2 import AttestationObject
from fido2 import cbor
from fido2.utils import websafe_encode
from fido2.ctap2 import AttestedCredentialData

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from OpenSSL import crypto

from eduid_userdb.credentials import Webauthn
from eduid_userdb.security import SecurityUser
from eduid_common.api.decorators import require_user, MarshalWith, UnmarshalWith
from eduid_common.api.utils import save_and_sync_user
from eduid_webapp.security.helpers import credentials_to_registered_keys, compile_credential_list
from eduid_webapp.security.schemas import WebauthnOptionsResponseSchema, WebauthnRegisterRequestSchema
from eduid_webapp.security.schemas import SecurityResponseSchema, RemoveWebauthnTokenRequestSchema
from eduid_webapp.security.schemas import VerifyWithWebauthnTokenRequestSchema
from eduid_webapp.security.schemas import VerifyWithWebauthnTokenResponseSchema

WEBAUTHN_SERVER = None

def update_webauthn_server(rp_id, name='eduID security API'):
    rp = RelyingParty(rp_id, name)
    server = Fido2Server(rp)
    global WEBAUTHN_SERVER
    WEBAUTHN_SERVER = server
    return server

def get_webauthn_server():
    if WEBAUTHN_SERVER is not None:
        return WEBAUTHN_SERVER
    return update_webauthn_server(current_app.config['FIDO2_RP_ID'])

def make_credentials(creds):
    credentials = []
    for cred in creds:
        cred_data = base64.b64decode(cred.credential_data.encode('ascii'))
        credential_data, rest = AttestedCredentialData.unpack_from(cred_data)
        if rest:
            continue
        credentials.append(credential_data)
    return credentials

webauthn_views = Blueprint('webauthn', __name__, url_prefix='/webauthn', template_folder='templates')

@webauthn_views.route('/register/begin', methods=['GET'])
@MarshalWith(WebauthnOptionsResponseSchema)
@require_user
def registration_begin(user):
    user_webauthn_tokens = user.credentials.filter(Webauthn)
    if user_webauthn_tokens.count >= current_app.config['WEBAUTHN_MAX_ALLOWED_TOKENS']:
        current_app.logger.error('User tried to register more than {} tokens.'.format(
            current_app.config['WEBAUTHN_MAX_ALLOWED_TOKENS']))
        resp = {'_status': 'error', 'message': 'security.webauthn.max_allowed_tokens'}
        cbor_resp = cbor.dumps(resp)
        return Response(response=cbor_resp, status=200, mimetype='application/cbor')
    creds = make_credentials(user_webauthn_tokens.to_list())
    server = get_webauthn_server()
    if user.surname is None or user.display_name is None:
        resp = {'_status': 'error', 'message': 'security.webauthn-missing-pdata'}
        cbor_resp = cbor.dumps(resp)
        return Response(response=cbor_resp, status=200, mimetype='application/cbor')
    registration_data, state = server.register_begin({
        'id': str(user.user_id).encode('ascii'),
        'name': user.surname,
        'displayName': user.display_name,
        'icon': ''
    }, creds)
    session['_webauthn_state_'] = state

    current_app.logger.info('User {} has started registration of a webauthn token'.format(user))
    current_app.logger.debug('Webauthn Registration data: {}.'.format(registration_data))
    current_app.stats.count(name='webauthn_register_begin')

    cbor_data = cbor.dumps(registration_data)
    current_app.logger.debug('CBOR encoded Registration data: {}.'.format(cbor_data))
    return Response(response=cbor_data, status=200, mimetype='application/cbor')

@webauthn_views.route('/register/complete', methods=['POST'])
@UnmarshalWith(WebauthnRegisterRequestSchema)
@MarshalWith(SecurityResponseSchema)
@require_user
def registration_complete(user, credential_id, attestation_object, client_data, description):
    security_user = SecurityUser.from_user(user, current_app.private_userdb)
    server = get_webauthn_server()

    attestation = base64.b64decode(attestation_object)
    att_obj = AttestationObject(attestation)
    client_data = base64.b64decode(client_data)
    cdata_obj = ClientData(client_data)
    state = session['_webauthn_state_']
    auth_data = server.register_complete(state, cdata_obj, att_obj)

    cred_data = auth_data.credential_data
    current_app.logger.debug('Proccessed Webauthn credential data: {}.'.format(cred_data))

    credential = Webauthn(
        keyhandle = credential_id,
        credential_data = base64.b64encode(cred_data).decode('ascii'),
        app_id = current_app.config['FIDO2_RP_ID'],
        attest_obj = base64.b64encode(attestation).decode('ascii'),
        description = description,
        application = 'security'
        )

    security_user.credentials.add(credential)
    save_and_sync_user(security_user)
    current_app.stats.count(name='webauthn_register_complete')
    current_app.logger.info('User {} has completed registration of a webauthn token'.format(security_user))
    return {
        'message': 'security.webauthn_register_success',
        'credentials': compile_credential_list(security_user)
    }

@webauthn_views.route('/remove', methods=['POST'])
@UnmarshalWith(RemoveWebauthnTokenRequestSchema)
@MarshalWith(SecurityResponseSchema)
@require_user
def remove(user, credential_key):
    security_user = SecurityUser.from_user(user, current_app.private_userdb)
    token_to_remove = security_user.credentials.filter(Webauthn).find(credential_key)
    if token_to_remove:
        security_user.credentials.remove(credential_key)
        save_and_sync_user(security_user)
        current_app.stats.count(name='webauthn_token_remove')
    return {
        'message': 'security.webauthn-token-removed',
        'credentials': compile_credential_list(security_user)
    }

@webauthn_views.route('/verify', methods=['POST'])
@UnmarshalWith(VerifyWithWebauthnTokenRequestSchema)
@MarshalWith(VerifyWithWebauthnTokenResponseSchema)
@require_user
def verify(user, key_handle, signature_data, client_data):
    challenge = session.pop('_u2f_challenge_')
    if not challenge:
        current_app.logger.error('Found no U2F challenge data in session.')
        return {'_error': True, 'message': 'security.u2f.missing_challenge_data'}
    data = {
        'keyHandle': key_handle,
        'signatureData': signature_data,
        'clientData': client_data
    }
    device, c, t = complete_authentication(challenge, data, current_app.config['U2F_FACETS'])
    current_app.stats.count(name='u2f_verify')
    return {'key_handle': device['keyHandle'], 'counter': c, 'touch': t}
<commit_msg>create fido2 server on the fly<commit_after># -*- coding: utf-8 -*-

from __future__ import print_function, absolute_import, unicode_literals

import struct
import json
import base64
from flask import Blueprint, session, Response
from flask import current_app, request

from fido2.client import ClientData
from fido2.server import Fido2Server, RelyingParty
from fido2.ctap2 import AttestationObject
from fido2 import cbor
from fido2.utils import websafe_encode
from fido2.ctap2 import AttestedCredentialData

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from OpenSSL import crypto

from eduid_userdb.credentials import Webauthn
from eduid_userdb.security import SecurityUser
from eduid_common.api.decorators import require_user, MarshalWith, UnmarshalWith
from eduid_common.api.utils import save_and_sync_user
from eduid_webapp.security.helpers import credentials_to_registered_keys, compile_credential_list
from eduid_webapp.security.schemas import WebauthnOptionsResponseSchema, WebauthnRegisterRequestSchema
from eduid_webapp.security.schemas import SecurityResponseSchema, RemoveWebauthnTokenRequestSchema
from eduid_webapp.security.schemas import VerifyWithWebauthnTokenRequestSchema
from eduid_webapp.security.schemas import VerifyWithWebauthnTokenResponseSchema

def get_webauthn_server(rp_id, name='eduID security API'):
    rp = RelyingParty(rp_id, name)
    return Fido2Server(rp)

def make_credentials(creds):
    credentials = []
    for cred in creds:
        cred_data = base64.b64decode(cred.credential_data.encode('ascii'))
        credential_data, rest = AttestedCredentialData.unpack_from(cred_data)
        if rest:
            continue
        credentials.append(credential_data)
    return credentials

webauthn_views = Blueprint('webauthn', __name__, url_prefix='/webauthn', template_folder='templates')

@webauthn_views.route('/register/begin', methods=['GET'])
@MarshalWith(WebauthnOptionsResponseSchema)
@require_user
def registration_begin(user):
    user_webauthn_tokens = user.credentials.filter(Webauthn)
    if user_webauthn_tokens.count >= current_app.config['WEBAUTHN_MAX_ALLOWED_TOKENS']:
        current_app.logger.error('User tried to register more than {} tokens.'.format(
            current_app.config['WEBAUTHN_MAX_ALLOWED_TOKENS']))
        resp = {'_status': 'error', 'message': 'security.webauthn.max_allowed_tokens'}
        cbor_resp = cbor.dumps(resp)
        return Response(response=cbor_resp, status=200, mimetype='application/cbor')
    creds = make_credentials(user_webauthn_tokens.to_list())
    server = get_webauthn_server()
    if user.surname is None or user.display_name is None:
        resp = {'_status': 'error', 'message': 'security.webauthn-missing-pdata'}
        cbor_resp = cbor.dumps(resp)
        return Response(response=cbor_resp, status=200, mimetype='application/cbor')
    registration_data, state = server.register_begin({
        'id': str(user.user_id).encode('ascii'),
        'name': user.surname,
        'displayName': user.display_name,
        'icon': ''
    }, creds)
    session['_webauthn_state_'] = state

    current_app.logger.info('User {} has started registration of a webauthn token'.format(user))
    current_app.logger.debug('Webauthn Registration data: {}.'.format(registration_data))
    current_app.stats.count(name='webauthn_register_begin')

    cbor_data = cbor.dumps(registration_data)
    current_app.logger.debug('CBOR encoded Registration data: {}.'.format(cbor_data))
    return Response(response=cbor_data, status=200, mimetype='application/cbor')

@webauthn_views.route('/register/complete', methods=['POST'])
@UnmarshalWith(WebauthnRegisterRequestSchema)
@MarshalWith(SecurityResponseSchema)
@require_user
def registration_complete(user, credential_id, attestation_object, client_data, description):
    security_user = SecurityUser.from_user(user, current_app.private_userdb)
    server = get_webauthn_server()

    attestation = base64.b64decode(attestation_object)
    att_obj = AttestationObject(attestation)
    client_data = base64.b64decode(client_data)
    cdata_obj = ClientData(client_data)
    state = session['_webauthn_state_']
    auth_data = server.register_complete(state, cdata_obj, att_obj)

    cred_data = auth_data.credential_data
    current_app.logger.debug('Proccessed Webauthn credential data: {}.'.format(cred_data))

    credential = Webauthn(
        keyhandle = credential_id,
        credential_data = base64.b64encode(cred_data).decode('ascii'),
        app_id = current_app.config['FIDO2_RP_ID'],
        attest_obj = base64.b64encode(attestation).decode('ascii'),
        description = description,
        application = 'security'
        )

    security_user.credentials.add(credential)
    save_and_sync_user(security_user)
    current_app.stats.count(name='webauthn_register_complete')
    current_app.logger.info('User {} has completed registration of a webauthn token'.format(security_user))
    return {
        'message': 'security.webauthn_register_success',
        'credentials': compile_credential_list(security_user)
    }

@webauthn_views.route('/remove', methods=['POST'])
@UnmarshalWith(RemoveWebauthnTokenRequestSchema)
@MarshalWith(SecurityResponseSchema)
@require_user
def remove(user, credential_key):
    security_user = SecurityUser.from_user(user, current_app.private_userdb)
    token_to_remove = security_user.credentials.filter(Webauthn).find(credential_key)
    if token_to_remove:
        security_user.credentials.remove(credential_key)
        save_and_sync_user(security_user)
        current_app.stats.count(name='webauthn_token_remove')
    return {
        'message': 'security.webauthn-token-removed',
        'credentials': compile_credential_list(security_user)
    }

@webauthn_views.route('/verify', methods=['POST'])
@UnmarshalWith(VerifyWithWebauthnTokenRequestSchema)
@MarshalWith(VerifyWithWebauthnTokenResponseSchema)
@require_user
def verify(user, key_handle, signature_data, client_data):
    challenge = session.pop('_u2f_challenge_')
    if not challenge:
        current_app.logger.error('Found no U2F challenge data in session.')
        return {'_error': True, 'message': 'security.u2f.missing_challenge_data'}
    data = {
        'keyHandle': key_handle,
        'signatureData': signature_data,
        'clientData': client_data
    }
    device, c, t = complete_authentication(challenge, data, current_app.config['U2F_FACETS'])
    current_app.stats.count(name='u2f_verify')
    return {'key_handle': device['keyHandle'], 'counter': c, 'touch': t}
<|endoftext|>


<commit_before>"""
File testing math.py performance.
"""

import friendly_computing_machine as fcm
import numpy as np
import pytest

def test_add():
    assert fcm.math.add(5, 2) == 7
    assert np.allclose(fcm.math.add(2.1, 3.6), 5.7)

def test_multiply():
    assert fcm.math.multiply(1, 2) == 2
    assert fcm.math.multiply(3, 2) == 6
    assert np.allclose(fcm.math.multiply(2.4, 6.9), 16.56)

def test_subtract():
    assert fcm.math.subtract(10, 8) == 2
    assert fcm.math.subtract(8, 10) == -2
    assert np.allclose(fcm.math.subtract(5.6, 3.1), 2.5)

def test_divide():
    assert fcm.math.divide(10, 2) == 5.0
    assert fcm.math.divide(10, 4) == 2.50
    assert np.allclose(fcm.math.divide(6.3, 2.4), 2.625)

def test_int_division():
    assert fcm.math.int_division(10, 2) == 5
    assert fcm.math.int_division(10, 3) == 3
    assert fcm.math.int_division(10, 4) == 2

def test_power():
    assert fcm.math.power(2, 0) == 1
    assert fcm.math.power(1, 5) == 1
    assert fcm.math.power(2, 4) == 16
    assert fcm.math.power(3, 3) == 27

<commit_msg>Added more tests.<commit_after>"""
File testing math.py performance.
"""

import friendly_computing_machine as fcm
import numpy as np
import pytest

def test_add():
    assert fcm.math.add(5, 2) == 7
    assert np.allclose(fcm.math.add(2.1, 3.6), 5.7)

def test_multiply():
    assert fcm.math.multiply(1, 2) == 2
    assert fcm.math.multiply(3, 2) == 6
    assert np.allclose(fcm.math.multiply(2.4, 6.9), 16.56)
    assert fcm.math.multiply(1, 0) == 0

def test_subtract():
    assert fcm.math.subtract(10, 8) == 2
    assert fcm.math.subtract(8, 10) == -2
    assert np.allclose(fcm.math.subtract(5.6, 3.1), 2.5)

def test_divide():
    assert fcm.math.divide(10, 2) == 5.0
    assert fcm.math.divide(10, 4) == 2.50
    assert np.allclose(fcm.math.divide(6.3, 2.4), 2.625)

def test_int_division():
    assert fcm.math.int_division(10, 2) == 5
    assert fcm.math.int_division(10, 3) == 3
    assert fcm.math.int_division(10, 4) == 2

def test_power():
    assert fcm.math.power(2, 0) == 1
    assert fcm.math.power(1, 5) == 1
    assert fcm.math.power(2, 4) == 16
    assert fcm.math.power(3, 3) == 27

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# Copyright 2012 splinter authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

try:
    import unittest2 as unittest
except ImportError:
    import unittest

from splinter.meta import InheritedDocs

class SuperClass(object):
    __metaclass__ = InheritedDocs

    def say_hello(self):
        """
        Says hello
        """
        pass

class SubClass(SuperClass):

    def say_hello(self):
        print "hello"

    @property
    def name(self):
        """
        Stores the name
        """
        pass

class SubSubClass(SubClass):

    def say_hello(self):
        print "I can't say hello"

    say_hi = say_hello

    @property
    def name(self):
        pass

class MetaTest(unittest.TestCase):

    def test_should_include_docs_from_superclass(self):
        "should include doc from superclass"
        self.assertEqual(SuperClass.say_hello.__doc__, SubClass.say_hello.__doc__)

    def test_should_include_docs_from_any_class_in_hierarchy(self):
        "should include doc from any class in hierarchy"
        self.assertEqual(SuperClass.say_hello.__doc__, SubSubClass.say_hello.__doc__)

    def test_change_docs_for_readonly_properties(self):
        "should also change docs for readonly properties"
        self.assertEqual(SubClass.name.__doc__, SubSubClass.name.__doc__)

    def test_should_not_touch_the_class_type(self):
        "shouldn't touch the type of the object"
        self.assertEqual('SubSubClass', SubSubClass.__name__)
<commit_msg>tests/test_meta.py is now pep8 certified<commit_after># -*- coding: utf-8 -*-

# Copyright 2012 splinter authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

try:
    import unittest2 as unittest
except ImportError:
    import unittest

from splinter.meta import InheritedDocs

class SuperClass(object):
    __metaclass__ = InheritedDocs

    def say_hello(self):
        """
        Says hello
        """
        pass

class SubClass(SuperClass):

    def say_hello(self):
        print "hello"

    @property
    def name(self):
        """
        Stores the name
        """
        pass

class SubSubClass(SubClass):

    def say_hello(self):
        print "I can't say hello"

    say_hi = say_hello

    @property
    def name(self):
        pass

class MetaTest(unittest.TestCase):

    def test_should_include_docs_from_superclass(self):
        "should include doc from superclass"
        self.assertEqual(
            SuperClass.say_hello.__doc__,
            SubClass.say_hello.__doc__
        )

    def test_should_include_docs_from_any_class_in_hierarchy(self):
        "should include doc from any class in hierarchy"
        self.assertEqual(
            SuperClass.say_hello.__doc__,
            SubSubClass.say_hello.__doc__
        )

    def test_change_docs_for_readonly_properties(self):
        "should also change docs for readonly properties"
        self.assertEqual(SubClass.name.__doc__, SubSubClass.name.__doc__)

    def test_should_not_touch_the_class_type(self):
        "shouldn't touch the type of the object"
        self.assertEqual('SubSubClass', SubSubClass.__name__)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (C) 2010, 2011, 2012 Sebastian Wiesner <lunaryorn@gmail.com>

# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.

# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
# for more details.

# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from __future__ import (print_function, division, unicode_literals,
                        absolute_import)

import sys
import re
import os
import subprocess
from distutils.filelist import FileList
if sys.version_info[0] < 3:
    from codecs import open
    from urlparse import urlparse

import py.path
import pytest
from docutils import io, readers
from docutils.core import publish_doctree, Publisher
from docutils.transforms import TransformError

TEST_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
SOURCE_DIRECTORY = os.path.abspath(os.path.join(
    TEST_DIRECTORY, os.pardir))
MANIFEST = os.path.join(SOURCE_DIRECTORY, 'MANIFEST.in')
README = os.path.join(SOURCE_DIRECTORY, 'README.rst')

# Files in the repository that don't need to be present in the sdist
REQUIRED_BLACKLIST = [
    r'^\.git.+',
    r'\.travis\.yml$',
    r'^MANIFEST\.in$',
    r'^Makefile$',
    r'^Vagrantfile$',
    r'^Cheffile(\.lock)?$',
    r'^vendor/cookbooks/.*$',
]

def _get_required_files():
    if not os.path.isdir(os.path.join(SOURCE_DIRECTORY, '.git')):
        pytest.skip('Not in git clone')
    git = py.path.local.sysfind('git')
    if not git:
        pytest.skip('git not available')
    ls_files = subprocess.Popen(['git', 'ls-files'], cwd=SOURCE_DIRECTORY,
                                stdout=subprocess.PIPE)
    output = ls_files.communicate()[0].decode('utf-8')
    for filename in output.splitlines():
        if not any(re.search(p, filename) for p in REQUIRED_BLACKLIST):
            yield filename

def _get_manifest_files():
    filelist = FileList()
    old_wd = os.getcwd()
    try:
        os.chdir(SOURCE_DIRECTORY)
        filelist.findall()
    finally:
        os.chdir(old_wd)
    with open(MANIFEST, 'r', encoding='utf-8') as source:
        for line in source:
            filelist.process_template_line(line.strip())
    return filelist.files

def trim_docstring(text):
    """
    Trim indentation and blank lines from docstring text & return it.

    See PEP 257.
    """
    if not text:
        return text
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = text.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxint
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxint:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

ALLOWED_SCHEMES = '''file ftp gopher hdl http https imap mailto mms news nntp
prospero rsync rtsp rtspu sftp shttp sip sips snews svn svn+ssh telnet
wais'''.split()

def render_readme_like_pypi(source, output_encoding='unicode'):
    """
    Render a ReST document just like PyPI does.
    """
    # Dedent all lines of `source`.
    source = trim_docstring(source)

    settings_overrides = {
        'raw_enabled': 0,  # no raw HTML code
        'file_insertion_enabled': 0,  # no file/URL access
        'halt_level': 2,  # at warnings or errors, raise an exception
        'report_level': 5,  # never report problems with the reST code
        }

    parts = None

    # Convert reStructuredText to HTML using Docutils.
    document = publish_doctree(source=source,
        settings_overrides=settings_overrides)

    for node in document.traverse():
        if node.tagname == '#text':
            continue
        if node.hasattr('refuri'):
            uri = node['refuri']
        elif node.hasattr('uri'):
            uri = node['uri']
        else:
            continue
        o = urlparse(uri)
        if o.scheme not in ALLOWED_SCHEMES:
            raise TransformError('link scheme not allowed: {0}'.format(uri))

    # now turn the transformed document into HTML
    reader = readers.doctree.Reader(parser_name='null')
    pub = Publisher(reader, source=io.DocTreeInput(document),
        destination_class=io.StringOutput)
    pub.set_writer('html')
    pub.process_programmatic_settings(None, settings_overrides, None)
    pub.set_destination(None, None)
    pub.publish()
    parts = pub.writer.parts

    output = parts['body']

    if output_encoding != 'unicode':
        output = output.encode(output_encoding)

    return output

def test_manifest_complete():
    required_files = sorted(_get_required_files())
    included_files = sorted(_get_manifest_files())
    assert required_files == included_files

@pytest.mark.skipif(str('sys.version_info[0] > 2'))
def test_description_rendering():
    with open(README, 'r', encoding='utf-8') as source:
        output = render_readme_like_pypi(source.read())
    assert output
<commit_msg>Work around docutils bug in tests<commit_after># -*- coding: utf-8 -*-
# Copyright (C) 2010, 2011, 2012, 2013 Sebastian Wiesner <lunaryorn@gmail.com>

# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.

# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
# for more details.

# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from __future__ import (print_function, division, unicode_literals,
                        absolute_import)

import sys
import re
import os
import subprocess
from distutils.filelist import FileList
if sys.version_info[0] < 3:
    from codecs import open
    from urlparse import urlparse

import py.path
import pytest
import docutils.utils  # Work around Docutils bug 214
from docutils import io, readers
from docutils.core import publish_doctree, Publisher
from docutils.transforms import TransformError

TEST_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
SOURCE_DIRECTORY = os.path.abspath(os.path.join(
    TEST_DIRECTORY, os.pardir))
MANIFEST = os.path.join(SOURCE_DIRECTORY, 'MANIFEST.in')
README = os.path.join(SOURCE_DIRECTORY, 'README.rst')

# Files in the repository that don't need to be present in the sdist
REQUIRED_BLACKLIST = [
    r'^\.git.+',
    r'\.travis\.yml$',
    r'^MANIFEST\.in$',
    r'^Makefile$',
    r'^Vagrantfile$',
    r'^Cheffile(\.lock)?$',
    r'^vendor/cookbooks/.*$',
]

def _get_required_files():
    if not os.path.isdir(os.path.join(SOURCE_DIRECTORY, '.git')):
        pytest.skip('Not in git clone')
    git = py.path.local.sysfind('git')
    if not git:
        pytest.skip('git not available')
    ls_files = subprocess.Popen(['git', 'ls-files'], cwd=SOURCE_DIRECTORY,
                                stdout=subprocess.PIPE)
    output = ls_files.communicate()[0].decode('utf-8')
    for filename in output.splitlines():
        if not any(re.search(p, filename) for p in REQUIRED_BLACKLIST):
            yield filename

def _get_manifest_files():
    filelist = FileList()
    old_wd = os.getcwd()
    try:
        os.chdir(SOURCE_DIRECTORY)
        filelist.findall()
    finally:
        os.chdir(old_wd)
    with open(MANIFEST, 'r', encoding='utf-8') as source:
        for line in source:
            filelist.process_template_line(line.strip())
    return filelist.files

def trim_docstring(text):
    """
    Trim indentation and blank lines from docstring text & return it.

    See PEP 257.
    """
    if not text:
        return text
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = text.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxint
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxint:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

ALLOWED_SCHEMES = '''file ftp gopher hdl http https imap mailto mms news nntp
prospero rsync rtsp rtspu sftp shttp sip sips snews svn svn+ssh telnet
wais'''.split()

def render_readme_like_pypi(source, output_encoding='unicode'):
    """
    Render a ReST document just like PyPI does.
    """
    # Dedent all lines of `source`.
    source = trim_docstring(source)

    settings_overrides = {
        'raw_enabled': 0,  # no raw HTML code
        'file_insertion_enabled': 0,  # no file/URL access
        'halt_level': 2,  # at warnings or errors, raise an exception
        'report_level': 5,  # never report problems with the reST code
        }

    parts = None

    # Convert reStructuredText to HTML using Docutils.
    document = publish_doctree(source=source,
        settings_overrides=settings_overrides)

    for node in document.traverse():
        if node.tagname == '#text':
            continue
        if node.hasattr('refuri'):
            uri = node['refuri']
        elif node.hasattr('uri'):
            uri = node['uri']
        else:
            continue
        o = urlparse(uri)
        if o.scheme not in ALLOWED_SCHEMES:
            raise TransformError('link scheme not allowed: {0}'.format(uri))

    # now turn the transformed document into HTML
    reader = readers.doctree.Reader(parser_name='null')
    pub = Publisher(reader, source=io.DocTreeInput(document),
        destination_class=io.StringOutput)
    pub.set_writer('html')
    pub.process_programmatic_settings(None, settings_overrides, None)
    pub.set_destination(None, None)
    pub.publish()
    parts = pub.writer.parts

    output = parts['body']

    if output_encoding != 'unicode':
        output = output.encode(output_encoding)

    return output

def test_manifest_complete():
    required_files = sorted(_get_required_files())
    included_files = sorted(_get_manifest_files())
    assert required_files == included_files

@pytest.mark.skipif(str('sys.version_info[0] > 2'))
def test_description_rendering():
    with open(README, 'r', encoding='utf-8') as source:
        output = render_readme_like_pypi(source.read())
    assert output
<|endoftext|>