<commit_before>from django.db import models

# Create your models here.
<commit_msg>Proof of concept for dynamic schemas<commit_after>from mongoengine import (
    Document,
    StringField,
    ListField,
    GenericReferenceField,
    DictField,
    EmailField,
)

class DynamicSchema(Document):
    title = StringField(unique=True, required=True)
    name = StringField(unique=True, required=True)
    schema = DictField()

    def get_data_access_object(self):
        return type(
            self.name,
            (Document, ),
            { "name": StringField(),
              "title": StringField(),
              "email": EmailField(),
            })
<|endoftext|>


<commit_before>#
# Jasy - Web Tooling Framework
# Copyright 2013 Sebastian Werner
#

import jasy.core.Console as Console
import jasy.core.OutputManager as OutputManager
import jasy.core.FileManager as FileManager
import jasy.asset.Manager as AssetManager

class Profile():
    """
    Configuration object for the build profile of the current task
    """

    __destinationFolder = None

    __parts = None

    __styleFolder = None
    __scriptFolder = None
    __assetFolder = None
    __templateFolder = None

    __hashAssets = False

    __compressionLevel = 0
    __formattingLevel = 5

    def __init__(self, session):

        self.__session = session
        self.__parts = {}

    def getDestinationFolder(self):
        return self.__destinationFolder

    def setDestinationFolder(self, folder):
        self.__destinationFolder = folder

    def getStyleFolder(self):
        return self.__styleFolder

    def setStyleFolder(self, folder):
        self.__styleFolder = folder

    def getScriptFolder(self):
        return self.__scriptFolder

    def setScriptFolder(self, folder):
        self.__scriptFolder = folder

    def getAssetFolder(self):
        return self.__assetFolder

    def setAssetFolder(self, folder):
        self.__assetFolder = folder

    def getTemplateFolder(self):
        return self.__templateFolder

    def setTemplateFolder(self, folder):
        self.__templateFolder = folder

    def getHashAssets(self):
        return self.__hashAssets

    def setHashAssets(self, enable):
        self.__hashAssets = enable

    def getLoadScriptSource(self):
        return self.__loadScriptSource

    def setLoadScriptSource(self, enable):
        self.__loadScriptSource = enable

    def getCompressionLevel(self):
        return self.__compressionLevel

    def setCompressionLevel(self, level):
        self.__compressionLevel = level

    def getFormattingLevel(self):
        return self.__formattingLevel

    def setFormattingLevel(self, level):
        self.__formattingLevel = level

    def registerPart(self, name, className="", styleName="", templateName=""):
        if name in self.__parts:
            raise Exception("The part %s is already registered!")

        self.__parts[name] = {
            "class" : className,
            "style" : styleName,
            "template" : templateName
        }

    def build(self):

        parts = self.__parts

        # Initialize shared objects
        assetManager = AssetManager.AssetManager(self.__session).addSourceProfile()
        outputManager = OutputManager.OutputManager(self.__session, assetManager,
            compressionLevel=self.__compressionLevel, formattingLevel=self.__formattingLevel)
        fileManager = FileManager.FileManager(self.__session)

        scriptFolder = self.__scriptFolder.replace("{{destination}}", self.__destinationFolder)
        styleFolder = self.__styleFolder.replace("{{destination}}", self.__destinationFolder)
        assetFolder = self.__assetFolder.replace("{{destination}}", self.__destinationFolder)
        templateFolder = self.__templateFolder.replace("{{destination}}", self.__destinationFolder)

        if "kernel" in parts:

            Console.info("Building part kernel...")
            Console.indent()

            # Store kernel script
            kernelClass = parts["kernel"]["class"]
            outputManager.storeKernelScript("%s/kernel.js" % scriptFolder, bootCode="%s.boot();" % kernelClass)

            Console.outdent()

        for permutation in self.__session.permutate():

            if "main" in parts:

                Console.info("Building part main...")
                Console.indent()

                Console.outdent()

            for part in parts:

                if part in ("kernel", "main"):
                    continue

                Console.info("Building part %s", part)

<commit_msg>Continued work on profile class<commit_after>#
# Jasy - Web Tooling Framework
# Copyright 2013 Sebastian Werner
#

import jasy.core.Console as Console
import jasy.core.OutputManager as OutputManager
import jasy.core.FileManager as FileManager
import jasy.asset.Manager as AssetManager

class Profile():
    """
    Configuration object for the build profile of the current task
    """

    __destinationFolder = None

    __parts = None

    __styleFolder = None
    __scriptFolder = None
    __assetFolder = None
    __templateFolder = None

    __hashAssets = False

    __compressionLevel = 0
    __formattingLevel = 5

    def __init__(self, session):

        self.__session = session
        self.__parts = {}

    def getDestinationFolder(self):
        return self.__destinationFolder

    def setDestinationFolder(self, folder):
        self.__destinationFolder = folder

    def getStyleFolder(self):
        return self.__styleFolder

    def setStyleFolder(self, folder):
        self.__styleFolder = folder

    def getScriptFolder(self):
        return self.__scriptFolder

    def setScriptFolder(self, folder):
        self.__scriptFolder = folder

    def getAssetFolder(self):
        return self.__assetFolder

    def setAssetFolder(self, folder):
        self.__assetFolder = folder

    def getTemplateFolder(self):
        return self.__templateFolder

    def setTemplateFolder(self, folder):
        self.__templateFolder = folder

    def getHashAssets(self):
        return self.__hashAssets

    def setHashAssets(self, enable):
        self.__hashAssets = enable

    def getUseSource(self):
        return self.__useSource

    def setUseSource(self, enable):
        self.__useSource = enable

    def getCompressionLevel(self):
        return self.__compressionLevel

    def setCompressionLevel(self, level):
        self.__compressionLevel = level

    def getFormattingLevel(self):
        return self.__formattingLevel

    def setFormattingLevel(self, level):
        self.__formattingLevel = level

    def registerPart(self, name, className="", styleName="", templateName=""):
        if name in self.__parts:
            raise Exception("The part %s is already registered!")

        self.__parts[name] = {
            "class" : className,
            "style" : styleName,
            "template" : templateName
        }

    def build(self):

        parts = self.__parts

        # Initialize shared objects
        assetManager = AssetManager.AssetManager(self.__session)
        outputManager = OutputManager.OutputManager(self.__session, assetManager,
            compressionLevel=self.__compressionLevel, formattingLevel=self.__formattingLevel)
        fileManager = FileManager.FileManager(self.__session)

        scriptFolder = self.__scriptFolder.replace("{{destination}}", self.__destinationFolder)
        styleFolder = self.__styleFolder.replace("{{destination}}", self.__destinationFolder)
        assetFolder = self.__assetFolder.replace("{{destination}}", self.__destinationFolder)
        templateFolder = self.__templateFolder.replace("{{destination}}", self.__destinationFolder)

        if self.__useSource:
            assetManager.addSourceProfile()

        if "kernel" in parts:

            Console.info("Building part kernel...")
            Console.indent()

            # Store kernel script
            kernelClass = parts["kernel"]["class"]
            outputManager.storeKernelScript("%s/kernel.js" % scriptFolder, bootCode="%s.boot();" % kernelClass)

            Console.outdent()

        for permutation in self.__session.permutate():

            if "main" in parts:

                Console.info("Building part main...")
                Console.indent()

                Console.outdent()

            for part in parts:

                if part in ("kernel", "main"):
                    continue

                Console.info("Building part %s", part)

<|endoftext|>


<commit_before>""" Model for access to logp and grad functions """

import collections

from .core import auto_grad_logp, np
from .state import func_var_names

class BaseModel(object):
    def __init__(self):
        self._logp_cache = {}
        self._grad_cache = {}

    def logp(self, state):
        pass

    def grad(self, state):
        pass

    def __call__(self, state):
        return self.logp(state), self.grad(state)

    def clear_cache(self):
        del self._logp_cache
        del self._grad_cache
        self._logp_cache = {}
        self._grad_cache = {}

class SingleModel(BaseModel):
    """ A model for a logp function that returns both the cost function and
        the gradient. Caches values to improve performance. """

    def __init__(self, logp_func):
        super(SingleModel, self).__init__()
        self.logp_func = logp_func

    def logp(self, state):
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            logp_value, _ = self.logp_func(*state.values())
            return logp_value

        if frozen_state in self._logp_cache:
            logp_value = self._logp_cache[frozen_state]
        else:
            logp_value, grad_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value
            self._grad_cache[frozen_state] = grad_value

        return logp_value

    def grad(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            _, grad_value = self.logp_func(*state.values())
            return grad_value

        if frozen_state in self._grad_cache:
            grad_value = self._grad_cache[frozen_state]
        else:
            logp_value, grad_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value
            self._grad_cache[frozen_state] = grad_value

        return grad_value

class Model(BaseModel):
    """ A model for separate logp and grad_logp functions. """
    def __init__(self, logp_func, grad_func=None, grad_logp_flag=False):
        super(Model, self).__init__()
        self.logp_func = check_logp(logp_func)
        self.grad_func = check_grad_logp(logp_func, grad_func, grad_logp_flag)

    def logp(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            logp_value = self.logp_func(*state.values())
            return logp_value

        if frozen_state in self._logp_cache:
            logp_value = self._logp_cache[frozen_state]
        else:
            logp_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value

        return logp_value

    def grad(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            grad_value = grad_vec(self.grad_func, state)
            return grad_value

        #print(type(frozen_state), frozen_state)
        if frozen_state in self._grad_cache:
            grad_value = self._grad_cache[frozen_state]
        else:
            grad_value = grad_vec(self.grad_func, state)
            self._grad_cache[frozen_state] = grad_value

        return grad_value

def init_model(logp, grad_logp=None, grad_logp_flag=False):
    if grad_logp is True:
        return SingleModel(logp)
    else:
        return Model(logp, grad_logp, grad_logp_flag)

def grad_vec(grad_logp, state):
    """ grad_logp should be a function, or a dictionary of gradient functions,
        respective to each parameter in logp
    """
    if hasattr(grad_logp, '__call__'):
        # grad_logp is a single function
        return np.array([grad_logp(*state.values())])
    else:
        # got a dictionary instead
        return np.array([grad_logp[each](*state.values()) for each in state])

def check_logp(logp):
    if not hasattr(logp, '__call__'):
        raise TypeError("logp must be a function")
    elif logp.__code__.co_argcount == 0:
        raise ValueError("logp must have arguments")
    else:
        return logp

def check_grad_logp(logp, grad_logp, grad_logp_flag):
    var_names = func_var_names(logp)
    if grad_logp_flag and grad_logp is None:
        return auto_grad_logp(logp)
    elif grad_logp_flag and grad_logp != 'logp':
        # User defined grad_logp function
        if len(var_names) > 1 and len(grad_logp) != len(var_names):
            raise TypeError("grad_logp must be iterable with length equal"
                                " to the number of parameters in logp.")
        else:
            return grad_logp
    else:
        return grad_logp<commit_msg>Removed a commented print call<commit_after>""" Model for access to logp and grad functions """

import collections

from .core import auto_grad_logp, np
from .state import func_var_names

class BaseModel(object):
    def __init__(self):
        self._logp_cache = {}
        self._grad_cache = {}

    def logp(self, state):
        pass

    def grad(self, state):
        pass

    def __call__(self, state):
        return self.logp(state), self.grad(state)

    def clear_cache(self):
        del self._logp_cache
        del self._grad_cache
        self._logp_cache = {}
        self._grad_cache = {}

class SingleModel(BaseModel):
    """ A model for a logp function that returns both the cost function and
        the gradient. Caches values to improve performance. """

    def __init__(self, logp_func):
        super(SingleModel, self).__init__()
        self.logp_func = logp_func

    def logp(self, state):
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            logp_value, _ = self.logp_func(*state.values())
            return logp_value

        if frozen_state in self._logp_cache:
            logp_value = self._logp_cache[frozen_state]
        else:
            logp_value, grad_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value
            self._grad_cache[frozen_state] = grad_value

        return logp_value

    def grad(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            _, grad_value = self.logp_func(*state.values())
            return grad_value

        if frozen_state in self._grad_cache:
            grad_value = self._grad_cache[frozen_state]
        else:
            logp_value, grad_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value
            self._grad_cache[frozen_state] = grad_value

        return grad_value

class Model(BaseModel):
    """ A model for separate logp and grad_logp functions. """
    def __init__(self, logp_func, grad_func=None, grad_logp_flag=False):
        super(Model, self).__init__()
        self.logp_func = check_logp(logp_func)
        self.grad_func = check_grad_logp(logp_func, grad_func, grad_logp_flag)

    def logp(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            logp_value = self.logp_func(*state.values())
            return logp_value

        if frozen_state in self._logp_cache:
            logp_value = self._logp_cache[frozen_state]
        else:
            logp_value = self.logp_func(*state.values())
            self._logp_cache[frozen_state] = logp_value

        return logp_value

    def grad(self, state):
        # Freeze the state as a tuple so we can use it as a dictionary key
        frozen_state = state.freeze()
        if not isinstance(frozen_state, collections.Hashable):
            # uncacheable. a list, for instance.
            # better to not cache than blow up.
            grad_value = grad_vec(self.grad_func, state)
            return grad_value

        if frozen_state in self._grad_cache:
            grad_value = self._grad_cache[frozen_state]
        else:
            grad_value = grad_vec(self.grad_func, state)
            self._grad_cache[frozen_state] = grad_value

        return grad_value

def init_model(logp, grad_logp=None, grad_logp_flag=False):
    if grad_logp is True:
        return SingleModel(logp)
    else:
        return Model(logp, grad_logp, grad_logp_flag)

def grad_vec(grad_logp, state):
    """ grad_logp should be a function, or a dictionary of gradient functions,
        respective to each parameter in logp
    """
    if hasattr(grad_logp, '__call__'):
        # grad_logp is a single function
        return np.array([grad_logp(*state.values())])
    else:
        # got a dictionary instead
        return np.array([grad_logp[each](*state.values()) for each in state])

def check_logp(logp):
    if not hasattr(logp, '__call__'):
        raise TypeError("logp must be a function")
    elif logp.__code__.co_argcount == 0:
        raise ValueError("logp must have arguments")
    else:
        return logp

def check_grad_logp(logp, grad_logp, grad_logp_flag):
    var_names = func_var_names(logp)
    if grad_logp_flag and grad_logp is None:
        return auto_grad_logp(logp)
    elif grad_logp_flag and grad_logp != 'logp':
        # User defined grad_logp function
        if len(var_names) > 1 and len(grad_logp) != len(var_names):
            raise TypeError("grad_logp must be iterable with length equal"
                                " to the number of parameters in logp.")
        else:
            return grad_logp
    else:
        return grad_logp<|endoftext|>


<commit_before>"""
A standalone partial implementation of sbt
https://www.solutionsbytext.com/api-support/api-documentation/
"""

from .resources import RequireVBT, RequestVBT, Carrier, SendTemplateMessage, GetMessageStatus

__all__ = [
    'RequireVBT', 'SendTemplateMessage', 'Carrier', 'GetMessageStatus', 'RequestVBT'
]
<commit_msg>Update __init__.py<commit_after>"""
A standalone partial implementation of sbt
https://www.solutionsbytext.com/api-support/api-documentation/
"""

from .resources import RequireVBT, RequestVBT, Carrier, SendTemplateMessage, GetMessageStatus

__all__ = [
    'RequireVBT', 'SendTemplateMessage', 'Carrier', 'GetMessageStatus', 'RequestVBT'
]

__version__ = '0.0.1'
<|endoftext|>


<commit_before>import numpy as np
from pandas import DataFrame
from javelin.unitcell import UnitCell
from javelin.utils import get_atomic_number_symbol

class Structure(object):
    def __init__(self, symbols=None, numbers=None, unitcell=1, ncells=None,
                 positions=None, rotations=False, translations=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod() != numberOfAtoms:
            raise ValueError("Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z',
                                        'cartn_x', 'cartn_y', 'cartn_z'])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        self._recalculate_cartn()

    @property
    def number_of_atoms(self):
        return len(self.atoms)

    @property
    def xyz(self):
        return self.atoms[['x', 'y', 'z']].values

    @property
    def x(self):
        return self.atoms.x.values

    @property
    def y(self):
        return self.atoms.y.values

    @property
    def z(self):
        return self.atoms.z.values

    @property
    def xyz_cartn(self):
        return self.atoms[['cartn_x', 'cartn_y', 'cartn_z']].values

    def get_atom_symbols(self):
        return self.atoms.symbol.unique()

    def get_atom_Zs(self):
        return self.atoms.Z.unique()

    def get_atom_count(self):
        return self.atoms.symbol.value_counts()

    def get_atomic_numbers(self):
        return self.atoms.Z.values

    def get_chemical_symbols(self):
        return self.atoms.symbol.values

    def get_scaled_positions(self):
        return self.xyz

    def get_positions(self):
        return self.xyz_cartn

    def add_atom(self, i=0, j=0, k=0, site=0, Z=None, symbol=None, position=None):
        Z, symbol = get_atomic_number_symbol([Z], [symbol])
        if position is None:
            raise ValueError("position not provided")

        cartn = self.unitcell.cartesian(position)[0]

        self.atoms.loc[i, j, k, site] = [Z[0], symbol[0],
                                         position[0], position[1], position[2],
                                         cartn[0], cartn[1], cartn[2]]

        if self.rotations is not None:
            self.rotations[i, j, k] = [1, 0, 0, 0]

        if self.translations is not None:
            self.translations[i, j, k] = [0, 0, 0]

    def repeat(self, rep):
        """Repeat the cells a number of time along each dimension

        *rep* argument should be either three value like *(1,2,3)* or
        a single value *r* equivalent to *(r,r,r)*."""

        if isinstance(rep, int):
            rep = np.array((rep, rep, rep, 1))
        else:
            rep = np.append(rep, 1)

        ncells = np.array(self.atoms.index.max()) + 1

        x = np.tile(np.reshape(self.x, ncells), rep).flatten()
        y = np.tile(np.reshape(self.y, ncells), rep).flatten()
        z = np.tile(np.reshape(self.z, ncells), rep).flatten()
        Z = np.tile(np.reshape(self.get_atomic_numbers(), ncells), rep).flatten()

        miindex = get_miindex(0, ncells * rep)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z',
                                        'cartn_x', 'cartn_y', 'cartn_z'])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=Z)

        self.atoms.x = x
        self.atoms.y = y
        self.atoms.z = z

        self._recalculate_cartn()

    def _recalculate_cartn(self):
        self.atoms[['cartn_x', 'cartn_y', 'cartn_z']] = self.unitcell.cartesian(
            self.atoms[['x', 'y', 'z']].values +
            np.asarray([self.atoms.index.get_level_values(0).values,
                        self.atoms.index.get_level_values(1).values,
                        self.atoms.index.get_level_values(2).values]).T)

def axisAngle2Versor(x, y, z, angle, unit='degrees'):
    norm = np.linalg.norm([x, y, z])

    if norm == 0:
        raise ValueError("Vector must have non-zero length")

    x /= norm
    y /= norm
    z /= norm

    if unit == 'degrees':
        angle = np.deg2rad(angle)

    sw = np.sin(angle/2)
    return [np.cos(angle/2), x*sw, y*sw, z*sw]

def get_rotation_matrix(l, m, n, theta, unit='degrees'):

    norm = np.linalg.norm([l, m, n])

    if norm == 0:
        raise ValueError("Rotation vector must have non-zero length")

    l /= norm
    m /= norm
    n /= norm

    if unit == 'degrees':
        theta = np.deg2rad(theta)

    ct = np.cos(theta)
    st = np.sin(theta)
    return np.matrix([[l*l*(1-ct)+ct,   m*l*(1-ct)-n*st, n*l*(1-ct)+m*st],
                      [l*m*(1-ct)+n*st, m*m*(1-ct)+ct,   n*m*(1-ct)-l*st],
                      [l*n*(1-ct)-m*st, m*n*(1-ct)+l*st, n*n*(1-ct)+ct]]).T

def get_rotation_matrix_from_versor(w, x, y, z):
    return np.matrix([[1-2*y**2-2*z**2, 2*(x*y-z*w), 2*(x*z+y*w)],
                      [2*(x*y+z*w), 1-2*x**2-2*z**2, 2*(y*z-x*w)],
                      [2*(x*z-y*w), 2*(y*z+x*w), 1-2*x**2-2*y**2]]).T

def get_miindex(l, ncells):
    from pandas import MultiIndex

    if ncells is None:
        if l == 0:
            miindex = MultiIndex(levels=[[], [], [], []],
                                 labels=[[], [], [], []],
                                 names=['i', 'j', 'k', 'site'])
        else:
            miindex = MultiIndex.from_product([0, 0, 0, range(l)],
                                              names=['i', 'j', 'k', 'site'])
    else:
        miindex = MultiIndex.from_product([range(ncells[0]),
                                           range(ncells[1]),
                                           range(ncells[2]),
                                           range(ncells[3])],
                                          names=['i', 'j', 'k', 'site'])

    return miindex
<commit_msg>Add reindex by ncells to structure<commit_after>import numpy as np
from pandas import DataFrame
from javelin.unitcell import UnitCell
from javelin.utils import get_atomic_number_symbol

class Structure(object):
    def __init__(self, symbols=None, numbers=None, unitcell=1, ncells=None,
                 positions=None, rotations=False, translations=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod() != numberOfAtoms:
            raise ValueError("Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z',
                                        'cartn_x', 'cartn_y', 'cartn_z'])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        self._recalculate_cartn()

    @property
    def number_of_atoms(self):
        return len(self.atoms)

    @property
    def xyz(self):
        return self.atoms[['x', 'y', 'z']].values

    @property
    def x(self):
        return self.atoms.x.values

    @property
    def y(self):
        return self.atoms.y.values

    @property
    def z(self):
        return self.atoms.z.values

    @property
    def xyz_cartn(self):
        return self.atoms[['cartn_x', 'cartn_y', 'cartn_z']].values

    def get_atom_symbols(self):
        return self.atoms.symbol.unique()

    def get_atom_Zs(self):
        return self.atoms.Z.unique()

    def get_atom_count(self):
        return self.atoms.symbol.value_counts()

    def get_atomic_numbers(self):
        return self.atoms.Z.values

    def get_chemical_symbols(self):
        return self.atoms.symbol.values

    def get_scaled_positions(self):
        return self.xyz

    def get_positions(self):
        return self.xyz_cartn

    def add_atom(self, i=0, j=0, k=0, site=0, Z=None, symbol=None, position=None):
        Z, symbol = get_atomic_number_symbol([Z], [symbol])
        if position is None:
            raise ValueError("position not provided")

        cartn = self.unitcell.cartesian(position)[0]

        self.atoms.loc[i, j, k, site] = [Z[0], symbol[0],
                                         position[0], position[1], position[2],
                                         cartn[0], cartn[1], cartn[2]]

        if self.rotations is not None:
            self.rotations[i, j, k] = [1, 0, 0, 0]

        if self.translations is not None:
            self.translations[i, j, k] = [0, 0, 0]

    def repeat(self, rep):
        """Repeat the cells a number of time along each dimension

        *rep* argument should be either three value like *(1,2,3)* or
        a single value *r* equivalent to *(r,r,r)*."""

        if isinstance(rep, int):
            rep = np.array((rep, rep, rep, 1))
        else:
            rep = np.append(rep, 1)

        ncells = np.array(self.atoms.index.max()) + 1

        x = np.tile(np.reshape(self.x, ncells), rep).flatten()
        y = np.tile(np.reshape(self.y, ncells), rep).flatten()
        z = np.tile(np.reshape(self.z, ncells), rep).flatten()
        Z = np.tile(np.reshape(self.get_atomic_numbers(), ncells), rep).flatten()

        miindex = get_miindex(0, ncells * rep)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z',
                                        'cartn_x', 'cartn_y', 'cartn_z'])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=Z)

        self.atoms.x = x
        self.atoms.y = y
        self.atoms.z = z

        self._recalculate_cartn()

    def reindex(self, ncells):
        self.atoms.set_index(get_miindex(ncells=ncells), inplace=True)
        self._recalculate_cartn()

    def _recalculate_cartn(self):
        self.atoms[['cartn_x', 'cartn_y', 'cartn_z']] = self.unitcell.cartesian(
            self.atoms[['x', 'y', 'z']].values +
            np.asarray([self.atoms.index.get_level_values(0).values,
                        self.atoms.index.get_level_values(1).values,
                        self.atoms.index.get_level_values(2).values]).T)

def axisAngle2Versor(x, y, z, angle, unit='degrees'):
    norm = np.linalg.norm([x, y, z])

    if norm == 0:
        raise ValueError("Vector must have non-zero length")

    x /= norm
    y /= norm
    z /= norm

    if unit == 'degrees':
        angle = np.deg2rad(angle)

    sw = np.sin(angle/2)
    return [np.cos(angle/2), x*sw, y*sw, z*sw]

def get_rotation_matrix(l, m, n, theta, unit='degrees'):

    norm = np.linalg.norm([l, m, n])

    if norm == 0:
        raise ValueError("Rotation vector must have non-zero length")

    l /= norm
    m /= norm
    n /= norm

    if unit == 'degrees':
        theta = np.deg2rad(theta)

    ct = np.cos(theta)
    st = np.sin(theta)
    return np.matrix([[l*l*(1-ct)+ct,   m*l*(1-ct)-n*st, n*l*(1-ct)+m*st],
                      [l*m*(1-ct)+n*st, m*m*(1-ct)+ct,   n*m*(1-ct)-l*st],
                      [l*n*(1-ct)-m*st, m*n*(1-ct)+l*st, n*n*(1-ct)+ct]]).T

def get_rotation_matrix_from_versor(w, x, y, z):
    return np.matrix([[1-2*y**2-2*z**2, 2*(x*y-z*w), 2*(x*z+y*w)],
                      [2*(x*y+z*w), 1-2*x**2-2*z**2, 2*(y*z-x*w)],
                      [2*(x*z-y*w), 2*(y*z+x*w), 1-2*x**2-2*y**2]]).T

def get_miindex(l=0, ncells=None):
    from pandas import MultiIndex

    if ncells is None:
        if l == 0:
            miindex = MultiIndex(levels=[[], [], [], []],
                                 labels=[[], [], [], []],
                                 names=['i', 'j', 'k', 'site'])
        else:
            miindex = MultiIndex.from_product([0, 0, 0, range(l)],
                                              names=['i', 'j', 'k', 'site'])
    else:
        miindex = MultiIndex.from_product([range(ncells[0]),
                                           range(ncells[1]),
                                           range(ncells[2]),
                                           range(ncells[3])],
                                          names=['i', 'j', 'k', 'site'])

    return miindex
<|endoftext|>


<commit_before>from datetime import datetime, date, time
from pyutils.encoding import force_str, force_unicode
from time import strptime
import re

class Invalid(Exception):
    def __init__(self, path=(), messages=(), children=()):
        if not isinstance(messages, (list, tuple)):
            messages = [messages]
        self.messages = {path: list(messages)}
        self.add(children)

    def __str__(self):
        return force_str(unicode(self))

    def __unicode__(self):
        result = []
        for path, messages in self.messages.items():
            prefix = '.'.join(map(force_unicode, path)) + ': ' if path else ''
            for index, message in enumerate(messages):
                if index == 0:
                    result.append(prefix + message)
                else:
                    result.append(message.rjust(len(prefix)))

        if len(result) == 1:
            return result[0]
        return '\n' + '\n'.join(result)

    def add(self, errors):
        if not hasattr(errors, '__iter__'):
            errors = (errors,)

        for error in errors:
            for path, messages in error.messages.items():
                self.messages.setdefault(path, []).extend(messages)

class MaxLength(object):
    def __init__(self, max_length):
        self.max_length = max_length

    def __call__(self, value, path):
        if len(value) > self.max_length:
            raise Invalid(path, 'Ensure this value has at most %d characters '
                                '(it has %d).' % (self.max_length, len(value)))

class MinValue(object):
    def __init__(self, min_value):
        self.min_value = min_value

    def __call__(self, value, path):
        if value < self.min_value:
            raise Invalid(path, 'This value must be larger than %s.'
                                % self.min_value)

class MaxValue(object):
    def __init__(self, max_value):
        self.max_value = max_value

    def __call__(self, value, path):
        if value < self.min_value:
            raise Invalid(path, 'This value must be smaller than %s.'
                                % self.max_value)

class Equals(object):
    def __init__(self, value):
        self.value = value

    def __call__(self, value, path):
        if value != self.value:
            raise Invalid(path, 'This value must be equal to %s.'
                                % self.value)

class In(object):
    def __init__(self, choice):
        self.choice = choice

    def __call__(self, value, path):
        if value not in self.choice:
            raise Invalid(path, 'This value must be one of: %s'
                                % ', '.join(map(unicode, self.choice)))

email_re = re.compile(
    # dot-atom
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"
    # quoted-string
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"'
    # domain
    r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)'
    # literal form, ipv4 address (SMTP 4.1.3)
    r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$',
    re.IGNORECASE)

class EmailValidator(object):
    def __call__(self, value, path):
        if not email_re.match(value):
            # Trivial case failed. Try for possible IDN domain-part
            if value and u'@' in value:
                parts = value.split(u'@')
                try:
                    parts[-1] = parts[-1].encode('idna')
                except UnicodeError:
                    raise
            if not email_re.match(u'@'.join(parts)):
                raise Invalid(path, 'Enter a valid e-mail address.')

class Schema(object):
    default_validators = []
    empty_string_equals_None = True

    def __init__(self, null=False, optional=False, validators=None):
        self.null = null
        self.optional = optional
        self.validators = self.default_validators[:]
        if validators:
            self.validators.extend(validators)

    def convert(self, value, path=()):
        if self.empty_string_equals_None and value == '':
            value = None

        if value is None:
            if not self.null:
                raise Invalid(path, 'This value may not be None.')
            return None
        value = self._convert(value, path)

        errors = []
        for validator in self.validators:
            try:
                validator(value, path)
            except Invalid, error:
                errors.append(error)
        if errors:
            raise Invalid(path, children=errors)
        return value

    def _convert(self, value, path=()):
        raise NotImplementedError()

class NestedSchema(Schema):
    def __init__(self, schema=None, **kwargs):
        self.schema = schema
        super(NestedSchema, self).__init__(**kwargs)

class Dict(NestedSchema):
    def _convert(self, value, path):
        if not isinstance(value, dict):
            raise Invalid(path, 'This value must be a dict.')

        if self.schema is None:
            return dict(value)

        errors = []
        result = {}
        seen = set()
        for key, schema in self.schema.items():
            if schema.optional and key not in value:
                continue

            seen.add(key)
            try:
                result[key] = schema.convert(value[key], path + (key,))
            except Invalid, error:
                errors.append(error)

        error = None
        non_converted = set(value) - seen
        if non_converted:
            error = Invalid(path, 'Unconverted values: %s' % ', '.join(non_converted))
        if errors:
            if not error:
                error = Invalid(path)
            error.add(errors)
        if error is not None:
            raise error

        return result

class IterableSchema(NestedSchema):
    _type_error = None
    _type = None

    def _convert(self, value, path):
        if not hasattr(value, '__iter__') or isinstance(value, basestring):
            raise Invalid(path, self._type_error)

        if self.schema is None:
            return self._type(value)

        errors = []
        result = []
        for index, subvalue in enumerate(value):
            try:
                result.append(self.schema.convert(subvalue, path + (index,)))
            except Invalid, error:
                errors.append(error)

        if errors:
            raise Invalid(path, children=errors)

        return self._type(result)

class List(NestedSchema):
    _type_error = 'This value must be a list.'
    _type = list

class Tuple(NestedSchema):
    _type_error = 'This value must be a tuple.'
    _type = tuple

class Set(NestedSchema):
    _type_error = 'This value must be a set.'
    _type = tuple

class Generic(Schema):
    def _convert(self, value, path):
        if isinstance(value, str):
            value = force_unicode(value)
        return value

class String(Schema):
    # Let's wrap the converter in a list, so it won't become a method.
    _converters = [force_unicode]

    def __init__(self, blank=False, **kwargs):
        super(String, self).__init__(**kwargs)
        self.blank = blank
        self.empty_string_equals_None = not blank

    def _convert(self, value, path):
        for converter in self._converters:
            value = converter(value)
        if not value and not self.blank:
            raise Invalid(path, 'This value is required.')
        return value

class Blob(String):
    _converters = [force_str]

class Number(Schema):
    # Let's wrap the converter in a list, so it won't become a method.
    _converters = []
    _error = None

    def _convert(self, value, path):
        try:
            for converter in self._converters:
                value = converter(value)
            return value
        except ValueError:
            raise Invalid(path, self._error)

class Int(Number):
    _converters = [int]
    _error = 'This value must be an integer.'

class Long(Int):
    _converters = [long]

class Float(Number):
    _converters = [float]
    _error = 'This value must be a number.'

class Bool(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return value.lower() not in ('0', 'false')
        return bool(value)

class DateTime(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_datetime(value, path)
        if not isinstance(value, datetime):
            raise Invalid(path, 'Please provide a datetime object.')
        return value

class Date(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_date(value, path)
        if isinstance(value, datetime):
            return value.date()
        if not isinstance(value, date):
            raise Invalid(path, 'Please provide a date object.')
        return value

class Time(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_time(value, path)
        if isinstance(value, datetime):
            return value.time()
        if not isinstance(value, time):
            raise Invalid(path, 'Please provide a time object.')
        return value

class Email(String):
    validators = [MaxLength(254), EmailValidator()]

DATETIME_INPUT_FORMATS = (
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
    '%d.%m.%Y %H:%M:%S',     # '25.10.2006 14:30:59'
    '%d.%m.%Y %H:%M',        # '25.10.2006 14:30'
)

def parse_datetime(value, path):
    for format in DATETIME_INPUT_FORMATS:
        try:
            return datetime(*strptime(value, format)[:6])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid date/time.')

DATE_INPUT_FORMATS = (
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y',  # '2006-10-25', '10/25/2006', '10/25/06'
    '%d.%m.%Y', '%d.%m.%y',              # '25.10.2006', '25.10.06'
)

def parse_date(value, path):
    for format in DATE_INPUT_FORMATS:
        try:
            return date(*strptime(value, format)[:3])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid date.')

TIME_INPUT_FORMATS = (
    '%H:%M:%S',     # '14:30:59'
    '%H:%M',        # '14:30'
)

def parse_time(value, path):
    for format in TIME_INPUT_FORMATS:
        try:
            return time(*strptime(value, format)[3:6])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid time.')
<commit_msg>added OneOf schema which is valid if one of its subschemas is valid<commit_after>from datetime import datetime, date, time
from pyutils.encoding import force_str, force_unicode
from time import strptime
import re

class Invalid(Exception):
    def __init__(self, path=(), messages=(), children=()):
        if not isinstance(messages, (list, tuple)):
            messages = [messages]
        self.messages = {path: list(messages)}
        self.add(children)

    def __str__(self):
        return force_str(unicode(self))

    def __unicode__(self):
        result = []
        for path, messages in self.messages.items():
            prefix = '.'.join(map(force_unicode, path)) + ': ' if path else ''
            for index, message in enumerate(messages):
                if index == 0:
                    result.append(prefix + message)
                else:
                    result.append(message.rjust(len(prefix)))

        if len(result) == 1:
            return result[0]
        return '\n' + '\n'.join(result)

    def add(self, errors):
        if not hasattr(errors, '__iter__'):
            errors = (errors,)

        for error in errors:
            for path, messages in error.messages.items():
                self.messages.setdefault(path, []).extend(messages)

class MaxLength(object):
    def __init__(self, max_length):
        self.max_length = max_length

    def __call__(self, value, path):
        if len(value) > self.max_length:
            raise Invalid(path, 'Ensure this value has at most %d characters '
                                '(it has %d).' % (self.max_length, len(value)))

class MinValue(object):
    def __init__(self, min_value):
        self.min_value = min_value

    def __call__(self, value, path):
        if value < self.min_value:
            raise Invalid(path, 'This value must be larger than %s.'
                                % self.min_value)

class MaxValue(object):
    def __init__(self, max_value):
        self.max_value = max_value

    def __call__(self, value, path):
        if value < self.min_value:
            raise Invalid(path, 'This value must be smaller than %s.'
                                % self.max_value)

class Equals(object):
    def __init__(self, value):
        self.value = value

    def __call__(self, value, path):
        if value != self.value:
            raise Invalid(path, 'This value must be equal to %s.'
                                % self.value)

class In(object):
    def __init__(self, choice):
        self.choice = choice

    def __call__(self, value, path):
        if value not in self.choice:
            raise Invalid(path, 'This value must be one of: %s'
                                % ', '.join(map(unicode, self.choice)))

email_re = re.compile(
    # dot-atom
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"
    # quoted-string
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"'
    # domain
    r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)'
    # literal form, ipv4 address (SMTP 4.1.3)
    r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$',
    re.IGNORECASE)

class EmailValidator(object):
    def __call__(self, value, path):
        if not email_re.match(value):
            # Trivial case failed. Try for possible IDN domain-part
            if value and u'@' in value:
                parts = value.split(u'@')
                try:
                    parts[-1] = parts[-1].encode('idna')
                except UnicodeError:
                    raise
            if not email_re.match(u'@'.join(parts)):
                raise Invalid(path, 'Enter a valid e-mail address.')

class Schema(object):
    default_validators = []
    empty_string_equals_None = True

    def __init__(self, null=False, optional=False, validators=None):
        self.null = null
        self.optional = optional
        self.validators = self.default_validators[:]
        if validators:
            self.validators.extend(validators)

    def convert(self, value, path=()):
        if self.empty_string_equals_None and value == '':
            value = None

        if value is None:
            if not self.null:
                raise Invalid(path, 'This value may not be None.')
            return None
        value = self._convert(value, path)

        errors = []
        for validator in self.validators:
            try:
                validator(value, path)
            except Invalid, error:
                errors.append(error)
        if errors:
            raise Invalid(path, children=errors)
        return value

    def _convert(self, value, path=()):
        raise NotImplementedError()

class OneOf(Schema):
    def __init__(self, choice=(), **kwargs):
        self.choice = list(choice)
        super(OneOf, self).__init__(**kwargs)

    def _convert(self, value, path):
        for schema in self.choice:
            if isinstance(schema, (tuple, list)):
                checker, schema = schema
                if not checker(value):
                    continue
                return schema.convert(value, path)
            else:
                try:
                    return schema.convert(value, path)
                except Invalid:
                    pass
        raise Invalid(path, "This value doesn't match any acceptable schema.")

class NestedSchema(Schema):
    def __init__(self, schema=None, **kwargs):
        self.schema = schema
        super(NestedSchema, self).__init__(**kwargs)

class Dict(NestedSchema):
    def _convert(self, value, path):
        if not isinstance(value, dict):
            raise Invalid(path, 'This value must be a dict.')

        if self.schema is None:
            return dict(value)

        errors = []
        result = {}
        seen = set()
        for key, schema in self.schema.items():
            if schema.optional and key not in value:
                continue

            seen.add(key)
            try:
                result[key] = schema.convert(value[key], path + (key,))
            except Invalid, error:
                errors.append(error)

        error = None
        non_converted = set(value) - seen
        if non_converted:
            error = Invalid(path, 'Unconverted values: %s' % ', '.join(non_converted))
        if errors:
            if not error:
                error = Invalid(path)
            error.add(errors)
        if error is not None:
            raise error

        return result

class IterableSchema(NestedSchema):
    _type_error = None
    _type = None

    def _convert(self, value, path):
        if not hasattr(value, '__iter__') or isinstance(value, basestring):
            raise Invalid(path, self._type_error)

        if self.schema is None:
            return self._type(value)

        errors = []
        result = []
        for index, subvalue in enumerate(value):
            try:
                result.append(self.schema.convert(subvalue, path + (index,)))
            except Invalid, error:
                errors.append(error)

        if errors:
            raise Invalid(path, children=errors)

        return self._type(result)

class List(NestedSchema):
    _type_error = 'This value must be a list.'
    _type = list

class Tuple(NestedSchema):
    _type_error = 'This value must be a tuple.'
    _type = tuple

class Set(NestedSchema):
    _type_error = 'This value must be a set.'
    _type = tuple

class Generic(Schema):
    def _convert(self, value, path):
        if isinstance(value, str):
            value = force_unicode(value)
        return value

class String(Schema):
    # Let's wrap the converter in a list, so it won't become a method.
    _converters = [force_unicode]

    def __init__(self, blank=False, **kwargs):
        super(String, self).__init__(**kwargs)
        self.blank = blank
        self.empty_string_equals_None = not blank

    def _convert(self, value, path):
        for converter in self._converters:
            value = converter(value)
        if not value and not self.blank:
            raise Invalid(path, 'This value is required.')
        return value

class Blob(String):
    _converters = [force_str]

class Number(Schema):
    # Let's wrap the converter in a list, so it won't become a method.
    _converters = []
    _error = None

    def _convert(self, value, path):
        try:
            for converter in self._converters:
                value = converter(value)
            return value
        except ValueError:
            raise Invalid(path, self._error)

class Int(Number):
    _converters = [int]
    _error = 'This value must be an integer.'

class Long(Int):
    _converters = [long]

class Float(Number):
    _converters = [float]
    _error = 'This value must be a number.'

class Bool(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return value.lower() not in ('0', 'false')
        return bool(value)

class DateTime(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_datetime(value, path)
        if not isinstance(value, datetime):
            raise Invalid(path, 'Please provide a datetime object.')
        return value

class Date(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_date(value, path)
        if isinstance(value, datetime):
            return value.date()
        if not isinstance(value, date):
            raise Invalid(path, 'Please provide a date object.')
        return value

class Time(Schema):
    def _convert(self, value, path):
        if isinstance(value, basestring):
            return parse_time(value, path)
        if isinstance(value, datetime):
            return value.time()
        if not isinstance(value, time):
            raise Invalid(path, 'Please provide a time object.')
        return value

class Email(String):
    validators = [MaxLength(254), EmailValidator()]

DATETIME_INPUT_FORMATS = (
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
    '%d.%m.%Y %H:%M:%S',     # '25.10.2006 14:30:59'
    '%d.%m.%Y %H:%M',        # '25.10.2006 14:30'
)

def parse_datetime(value, path):
    for format in DATETIME_INPUT_FORMATS:
        try:
            return datetime(*strptime(value, format)[:6])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid date/time.')

DATE_INPUT_FORMATS = (
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y',  # '2006-10-25', '10/25/2006', '10/25/06'
    '%d.%m.%Y', '%d.%m.%y',              # '25.10.2006', '25.10.06'
)

def parse_date(value, path):
    for format in DATE_INPUT_FORMATS:
        try:
            return date(*strptime(value, format)[:3])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid date.')

TIME_INPUT_FORMATS = (
    '%H:%M:%S',     # '14:30:59'
    '%H:%M',        # '14:30'
)

def parse_time(value, path):
    for format in TIME_INPUT_FORMATS:
        try:
            return time(*strptime(value, format)[3:6])
        except ValueError:
            continue
    raise Invalid(path, 'Please enter a valid time.')
<|endoftext|>


<commit_before># Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""Base classes for our unit tests.

Allows overriding of flags for use of fakes, and some black magic for
inline callbacks.

"""

import os
import shutil
import tempfile
import uuid

import fixtures
import mock
from oslo.config import cfg
from oslo.messaging import conffixture as messaging_conffixture
from oslo.utils import timeutils
import six
import testtools

from manila.db import migration
from manila.db.sqlalchemy import api as db_api
from manila.db.sqlalchemy import models as db_models
from manila.openstack.common import log as logging
from manila import rpc
from manila import service
from manila.tests import conf_fixture
from manila.tests import fake_notifier

test_opts = [
    cfg.StrOpt('sqlite_clean_db',
               default='clean.sqlite',
               help='File name of clean sqlite database.'),
    cfg.BoolOpt('fake_tests',
                default=True,
                help='Whether to use everything for testing.'), ]

CONF = cfg.CONF
CONF.register_opts(test_opts)

LOG = logging.getLogger(__name__)

_DB_CACHE = None

class Database(fixtures.Fixture):

    def __init__(self, db_session, db_migrate, sql_connection, sqlite_db,
                 sqlite_clean_db):
        self.sql_connection = sql_connection
        self.sqlite_db = sqlite_db
        self.sqlite_clean_db = sqlite_clean_db
        self.engine = db_session.get_engine()
        self.engine.dispose()
        conn = self.engine.connect()
        if sql_connection == "sqlite://":
            self.setup_sqlite(db_migrate)
        else:
            testdb = os.path.join(CONF.state_path, sqlite_db)
            db_migrate.upgrade('head')
            if os.path.exists(testdb):
                return
        if sql_connection == "sqlite://":
            conn = self.engine.connect()
            self._DB = "".join(line for line in conn.connection.iterdump())
            self.engine.dispose()
        else:
            cleandb = os.path.join(CONF.state_path, sqlite_clean_db)
            shutil.copyfile(testdb, cleandb)

    def setUp(self):
        super(Database, self).setUp()
        if self.sql_connection == "sqlite://":
            conn = self.engine.connect()
            conn.connection.executescript(self._DB)
            self.addCleanup(self.engine.dispose)  # pylint: disable=E1101
        else:
            shutil.copyfile(
                os.path.join(CONF.state_path, self.sqlite_clean_db),
                os.path.join(CONF.state_path, self.sqlite_db),
            )

    def setup_sqlite(self, db_migrate):
        if db_migrate.version():
            return
        db_models.BASE.metadata.create_all(self.engine)
        db_migrate.stamp('head')

class StubOutForTesting(object):
    def __init__(self, parent):
        self.parent = parent

    def Set(self, obj, attr_name, new_attr):
        stub = mock.patch.object(obj, attr_name, new_attr)
        stub.start()
        self.parent.addCleanup(stub.stop)

class TestCase(testtools.TestCase):
    """Test case base class for all unit tests."""

    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        conf_fixture.set_defaults(CONF)
        CONF([], default_config_files=[])

        # NOTE(vish): We need a better method for creating fixtures for tests
        #             now that we have some required db setup for the system
        #             to work properly.
        self.start = timeutils.utcnow()

        self.log_fixture = self.useFixture(fixtures.FakeLogger())
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(
                db_api,
                migration,
                sql_connection=CONF.database.connection,
                sqlite_db=CONF.sqlite_db,
                sqlite_clean_db=CONF.sqlite_clean_db,
            )
        self.useFixture(_DB_CACHE)

        self.stubs = StubOutForTesting(self)
        self.injected = []
        self._services = []
        CONF.set_override('fatal_exception_format_errors', True)
        # This will be cleaned up by the NestedTempfile fixture
        CONF.set_override('lock_path', tempfile.mkdtemp())

        rpc.add_extra_exmods('manila.tests')
        self.addCleanup(rpc.clear_extra_exmods)
        self.addCleanup(rpc.cleanup)

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_driver = 'fake'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)
        rpc.init(CONF)

        fake_notifier.stub_notifier(self.stubs)

    def tearDown(self):
        """Runs after each test method to tear down test environment."""
        super(TestCase, self).tearDown()
        # Reset any overridden flags
        CONF.reset()

        # Stop any timers
        for x in self.injected:
            try:
                x.stop()
            except AssertionError:
                pass

        # Kill any services
        for x in self._services:
            try:
                x.kill()
            except Exception:
                pass

        # Delete attributes that don't start with _ so they don't pin
        # memory around unnecessarily for the duration of the test
        # suite
        for key in [k for k in self.__dict__.keys() if k[0] != '_']:
            del self.__dict__[key]

    def flags(self, **kw):
        """Override flag variables for a test."""
        for k, v in six.iteritems(kw):
            CONF.set_override(k, v)

    def start_service(self, name, host=None, **kwargs):
        host = host and host or uuid.uuid4().hex
        kwargs.setdefault('host', host)
        kwargs.setdefault('binary', 'manila-%s' % name)
        svc = service.Service.create(**kwargs)
        svc.start()
        self._services.append(svc)
        return svc

    # Useful assertions
    def assertDictMatch(self, d1, d2, approx_equal=False, tolerance=0.001):
        """Assert two dicts are equivalent.

        This is a 'deep' match in the sense that it handles nested
        dictionaries appropriately.

        NOTE:

            If you don't care (or don't know) a given value, you can specify
            the string DONTCARE as the value. This will cause that dict-item
            to be skipped.

        """
        def raise_assertion(msg):
            d1str = str(d1)
            d2str = str(d2)
            base_msg = ('Dictionaries do not match. %(msg)s d1: %(d1str)s '
                        'd2: %(d2str)s' %
                        {"msg": msg, "d1str": d1str, "d2str": d2str})
            raise AssertionError(base_msg)

        d1keys = set(d1.keys())
        d2keys = set(d2.keys())
        if d1keys != d2keys:
            d1only = d1keys - d2keys
            d2only = d2keys - d1keys
            raise_assertion('Keys in d1 and not d2: %(d1only)s. '
                            'Keys in d2 and not d1: %(d2only)s' %
                            {"d1only": d1only, "d2only": d2only})

        for key in d1keys:
            d1value = d1[key]
            d2value = d2[key]
            try:
                error = abs(float(d1value) - float(d2value))
                within_tolerance = error <= tolerance
            except (ValueError, TypeError):
                # If both values aren't convertable to float, just ignore
                # ValueError if arg is a str, TypeError if it's something else
                # (like None)
                within_tolerance = False

            if hasattr(d1value, 'keys') and hasattr(d2value, 'keys'):
                self.assertDictMatch(d1value, d2value)
            elif 'DONTCARE' in (d1value, d2value):
                continue
            elif approx_equal and within_tolerance:
                continue
            elif d1value != d2value:
                raise_assertion("d1['%(key)s']=%(d1value)s != "
                                "d2['%(key)s']=%(d2value)s" %
                                {
                                    "key": key,
                                    "d1value": d1value,
                                    "d2value": d2value
                                })

    def assertDictListMatch(self, L1, L2, approx_equal=False, tolerance=0.001):
        """Assert a list of dicts are equivalent."""
        def raise_assertion(msg):
            L1str = str(L1)
            L2str = str(L2)
            base_msg = ('List of dictionaries do not match: %(msg)s '
                        'L1: %(L1str)s L2: %(L2str)s' %
                        {"msg": msg, "L1str": L1str, "L2str": L2str})
            raise AssertionError(base_msg)

        L1count = len(L1)
        L2count = len(L2)
        if L1count != L2count:
            raise_assertion('Length mismatch: len(L1)=%(L1count)d != '
                            'len(L2)=%(L2count)d' %
                            {"L1count": L1count, "L2count": L2count})

        for d1, d2 in zip(L1, L2):
            self.assertDictMatch(d1, d2, approx_equal=approx_equal,
                                 tolerance=tolerance)

    def assertSubDictMatch(self, sub_dict, super_dict):
        """Assert a sub_dict is subset of super_dict."""
        self.assertTrue(set(sub_dict.keys()).issubset(set(super_dict.keys())))
        for k, sub_value in sub_dict.items():
            super_value = super_dict[k]
            if isinstance(sub_value, dict):
                self.assertSubDictMatch(sub_value, super_value)
            elif 'DONTCARE' in (sub_value, super_value):
                continue
            else:
                self.assertEqual(sub_value, super_value)

    def assertIn(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility.  Assert 'a' in 'b'."""
        try:
            f = super(TestCase, self).assertIn
        except AttributeError:
            self.assertTrue(a in b, *args, **kwargs)
        else:
            f(a, b, *args, **kwargs)

    def assertNotIn(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility.  Assert 'a' NOT in 'b'."""
        try:
            f = super(TestCase, self).assertNotIn
        except AttributeError:
            self.assertFalse(a in b, *args, **kwargs)
        else:
            f(a, b, *args, **kwargs)

    def assertIsInstance(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility."""
        try:
            f = super(TestCase, self).assertIsInstance
        except AttributeError:
            self.assertTrue(isinstance(a, b))
        else:
            f(a, b, *args, **kwargs)

    def assertIsNone(self, a, *args, **kwargs):
        """Python < v2.7 compatibility."""
        try:
            f = super(TestCase, self).assertIsNone
        except AttributeError:
            self.assertTrue(a is None)
        else:
            f(a, *args, **kwargs)
<commit_msg>Remove unused conf option 'fake_tests'<commit_after># Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""Base classes for our unit tests.

Allows overriding of flags for use of fakes, and some black magic for
inline callbacks.

"""

import os
import shutil
import tempfile
import uuid

import fixtures
import mock
from oslo.config import cfg
from oslo.messaging import conffixture as messaging_conffixture
from oslo.utils import timeutils
import six
import testtools

from manila.db import migration
from manila.db.sqlalchemy import api as db_api
from manila.db.sqlalchemy import models as db_models
from manila.openstack.common import log as logging
from manila import rpc
from manila import service
from manila.tests import conf_fixture
from manila.tests import fake_notifier

test_opts = [
    cfg.StrOpt('sqlite_clean_db',
               default='clean.sqlite',
               help='File name of clean sqlite database.'),
]

CONF = cfg.CONF
CONF.register_opts(test_opts)

LOG = logging.getLogger(__name__)

_DB_CACHE = None

class Database(fixtures.Fixture):

    def __init__(self, db_session, db_migrate, sql_connection, sqlite_db,
                 sqlite_clean_db):
        self.sql_connection = sql_connection
        self.sqlite_db = sqlite_db
        self.sqlite_clean_db = sqlite_clean_db
        self.engine = db_session.get_engine()
        self.engine.dispose()
        conn = self.engine.connect()
        if sql_connection == "sqlite://":
            self.setup_sqlite(db_migrate)
        else:
            testdb = os.path.join(CONF.state_path, sqlite_db)
            db_migrate.upgrade('head')
            if os.path.exists(testdb):
                return
        if sql_connection == "sqlite://":
            conn = self.engine.connect()
            self._DB = "".join(line for line in conn.connection.iterdump())
            self.engine.dispose()
        else:
            cleandb = os.path.join(CONF.state_path, sqlite_clean_db)
            shutil.copyfile(testdb, cleandb)

    def setUp(self):
        super(Database, self).setUp()
        if self.sql_connection == "sqlite://":
            conn = self.engine.connect()
            conn.connection.executescript(self._DB)
            self.addCleanup(self.engine.dispose)  # pylint: disable=E1101
        else:
            shutil.copyfile(
                os.path.join(CONF.state_path, self.sqlite_clean_db),
                os.path.join(CONF.state_path, self.sqlite_db),
            )

    def setup_sqlite(self, db_migrate):
        if db_migrate.version():
            return
        db_models.BASE.metadata.create_all(self.engine)
        db_migrate.stamp('head')

class StubOutForTesting(object):
    def __init__(self, parent):
        self.parent = parent

    def Set(self, obj, attr_name, new_attr):
        stub = mock.patch.object(obj, attr_name, new_attr)
        stub.start()
        self.parent.addCleanup(stub.stop)

class TestCase(testtools.TestCase):
    """Test case base class for all unit tests."""

    def setUp(self):
        """Run before each test method to initialize test environment."""
        super(TestCase, self).setUp()

        conf_fixture.set_defaults(CONF)
        CONF([], default_config_files=[])

        # NOTE(vish): We need a better method for creating fixtures for tests
        #             now that we have some required db setup for the system
        #             to work properly.
        self.start = timeutils.utcnow()

        self.log_fixture = self.useFixture(fixtures.FakeLogger())
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(
                db_api,
                migration,
                sql_connection=CONF.database.connection,
                sqlite_db=CONF.sqlite_db,
                sqlite_clean_db=CONF.sqlite_clean_db,
            )
        self.useFixture(_DB_CACHE)

        self.stubs = StubOutForTesting(self)
        self.injected = []
        self._services = []
        CONF.set_override('fatal_exception_format_errors', True)
        # This will be cleaned up by the NestedTempfile fixture
        CONF.set_override('lock_path', tempfile.mkdtemp())

        rpc.add_extra_exmods('manila.tests')
        self.addCleanup(rpc.clear_extra_exmods)
        self.addCleanup(rpc.cleanup)

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_driver = 'fake'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)
        rpc.init(CONF)

        fake_notifier.stub_notifier(self.stubs)

    def tearDown(self):
        """Runs after each test method to tear down test environment."""
        super(TestCase, self).tearDown()
        # Reset any overridden flags
        CONF.reset()

        # Stop any timers
        for x in self.injected:
            try:
                x.stop()
            except AssertionError:
                pass

        # Kill any services
        for x in self._services:
            try:
                x.kill()
            except Exception:
                pass

        # Delete attributes that don't start with _ so they don't pin
        # memory around unnecessarily for the duration of the test
        # suite
        for key in [k for k in self.__dict__.keys() if k[0] != '_']:
            del self.__dict__[key]

    def flags(self, **kw):
        """Override flag variables for a test."""
        for k, v in six.iteritems(kw):
            CONF.set_override(k, v)

    def start_service(self, name, host=None, **kwargs):
        host = host and host or uuid.uuid4().hex
        kwargs.setdefault('host', host)
        kwargs.setdefault('binary', 'manila-%s' % name)
        svc = service.Service.create(**kwargs)
        svc.start()
        self._services.append(svc)
        return svc

    # Useful assertions
    def assertDictMatch(self, d1, d2, approx_equal=False, tolerance=0.001):
        """Assert two dicts are equivalent.

        This is a 'deep' match in the sense that it handles nested
        dictionaries appropriately.

        NOTE:

            If you don't care (or don't know) a given value, you can specify
            the string DONTCARE as the value. This will cause that dict-item
            to be skipped.

        """
        def raise_assertion(msg):
            d1str = str(d1)
            d2str = str(d2)
            base_msg = ('Dictionaries do not match. %(msg)s d1: %(d1str)s '
                        'd2: %(d2str)s' %
                        {"msg": msg, "d1str": d1str, "d2str": d2str})
            raise AssertionError(base_msg)

        d1keys = set(d1.keys())
        d2keys = set(d2.keys())
        if d1keys != d2keys:
            d1only = d1keys - d2keys
            d2only = d2keys - d1keys
            raise_assertion('Keys in d1 and not d2: %(d1only)s. '
                            'Keys in d2 and not d1: %(d2only)s' %
                            {"d1only": d1only, "d2only": d2only})

        for key in d1keys:
            d1value = d1[key]
            d2value = d2[key]
            try:
                error = abs(float(d1value) - float(d2value))
                within_tolerance = error <= tolerance
            except (ValueError, TypeError):
                # If both values aren't convertable to float, just ignore
                # ValueError if arg is a str, TypeError if it's something else
                # (like None)
                within_tolerance = False

            if hasattr(d1value, 'keys') and hasattr(d2value, 'keys'):
                self.assertDictMatch(d1value, d2value)
            elif 'DONTCARE' in (d1value, d2value):
                continue
            elif approx_equal and within_tolerance:
                continue
            elif d1value != d2value:
                raise_assertion("d1['%(key)s']=%(d1value)s != "
                                "d2['%(key)s']=%(d2value)s" %
                                {
                                    "key": key,
                                    "d1value": d1value,
                                    "d2value": d2value
                                })

    def assertDictListMatch(self, L1, L2, approx_equal=False, tolerance=0.001):
        """Assert a list of dicts are equivalent."""
        def raise_assertion(msg):
            L1str = str(L1)
            L2str = str(L2)
            base_msg = ('List of dictionaries do not match: %(msg)s '
                        'L1: %(L1str)s L2: %(L2str)s' %
                        {"msg": msg, "L1str": L1str, "L2str": L2str})
            raise AssertionError(base_msg)

        L1count = len(L1)
        L2count = len(L2)
        if L1count != L2count:
            raise_assertion('Length mismatch: len(L1)=%(L1count)d != '
                            'len(L2)=%(L2count)d' %
                            {"L1count": L1count, "L2count": L2count})

        for d1, d2 in zip(L1, L2):
            self.assertDictMatch(d1, d2, approx_equal=approx_equal,
                                 tolerance=tolerance)

    def assertSubDictMatch(self, sub_dict, super_dict):
        """Assert a sub_dict is subset of super_dict."""
        self.assertTrue(set(sub_dict.keys()).issubset(set(super_dict.keys())))
        for k, sub_value in sub_dict.items():
            super_value = super_dict[k]
            if isinstance(sub_value, dict):
                self.assertSubDictMatch(sub_value, super_value)
            elif 'DONTCARE' in (sub_value, super_value):
                continue
            else:
                self.assertEqual(sub_value, super_value)

    def assertIn(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility.  Assert 'a' in 'b'."""
        try:
            f = super(TestCase, self).assertIn
        except AttributeError:
            self.assertTrue(a in b, *args, **kwargs)
        else:
            f(a, b, *args, **kwargs)

    def assertNotIn(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility.  Assert 'a' NOT in 'b'."""
        try:
            f = super(TestCase, self).assertNotIn
        except AttributeError:
            self.assertFalse(a in b, *args, **kwargs)
        else:
            f(a, b, *args, **kwargs)

    def assertIsInstance(self, a, b, *args, **kwargs):
        """Python < v2.7 compatibility."""
        try:
            f = super(TestCase, self).assertIsInstance
        except AttributeError:
            self.assertTrue(isinstance(a, b))
        else:
            f(a, b, *args, **kwargs)

    def assertIsNone(self, a, *args, **kwargs):
        """Python < v2.7 compatibility."""
        try:
            f = super(TestCase, self).assertIsNone
        except AttributeError:
            self.assertTrue(a is None)
        else:
            f(a, *args, **kwargs)
<|endoftext|>


<commit_before>#     Copyright 2015 Cedraro Andrea <a.cedraro@gmail.com>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
#    limitations under the License.

import utils
utils.AddVendorFolderToSysPath()

import argparse
import waitress
import handlers

def ParseArgs():
  parser = argparse.ArgumentParser()
  parser.add_argument( '--port', type = int, default = 0,
                       help = 'server port')

  return parser.parse_args()

def Main():
  args = ParseArgs()
  waitress.serve( handlers.app,
                  host = '127.0.0.1',
                  port = args.port )

if __name__ == "__main__":
  Main()
<commit_msg>Add command-line argument for server host<commit_after>#     Copyright 2015 Cedraro Andrea <a.cedraro@gmail.com>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
#    limitations under the License.

import utils
utils.AddVendorFolderToSysPath()

import argparse
import waitress
import handlers

def ParseArgs():
  parser = argparse.ArgumentParser()
  parser.add_argument( '--host', type = str, default = '127.0.0.1',
                       help = 'server host' )
  parser.add_argument( '--port', type = int, default = 0,
                       help = 'server port' )
  return parser.parse_args()

def Main():
  args = ParseArgs()
  waitress.serve( handlers.app,
                  host = args.host,
                  port = args.port )

if __name__ == "__main__":
  Main()
<|endoftext|>