<commit_before>"""
A function library of miscellaneous utils usually involving
editor selection or interactive work. Many UI commands are
located here, as they can be more specific than the core api
but still not dependent on a UI.
"""

import os
import logging
import maya.cmds as cmds
import pymel.core as pm

from pulse.vendor.mayacoretools import preservedSelection

from pulse.colors import *
from pulse.joints import *
from pulse.nodes import *
from pulse.shapes import *
from pulse.sym import *
import pulse.links
import pulse.skins

__all__ = [
    'centerSelectedJoints',
    'createOffsetForSelected',
    'disableColorOverrideForSelected',
    'disableSegmentScaleCompensateForSelected',
    'freezeOffsetMatricesForSelectedHierarchies',
    'freezePivotsForSelectedHierarchies',
    'freezeScalesForSelectedHierarchies',
    'getDetailedChannelBoxAttrs',
    'getNamedColor',
    'getSelectedTransforms',
    'insertJointForSelected',
    'interactiveOrientForSelected',
    'isDetailedChannelBoxEnabled',
    'linkSelected',
    'matchJointRotationToOrientForSelected',
    'mirrorSelected',
    'orientToJointForSelected',
    'orientToWorldForSelected',
    'pairSelected',
    'parentSelected',
    'parentSelectedInOrder',
    'rotateSelectedComponentsAroundAxis',
    'rotateSelectedOrientsAroundAxis',
    'saveSceneIfDirty',
    'saveSkinWeightsForSelected',
    'setDetailedChannelBoxEnabled',
    'setOverrideColorForSelected',
    'snapToLinkForSelected',
    'toggleDetailedChannelBoxForSelected',
    'toggleLocalRotationAxesForSelected',
    'unfreezeOffsetMatricesForSelectedHierarchies',
    'unlinkSelected',
    'unpairSelected',
]

LOG = logging.getLogger(__name__)

def saveSceneIfDirty(prompt=True):
    """
    Prompt the user to save if the scene is modified, or has never been saved.

    Returns True if the save was successful, or the scene has not been modified.

    Args:
        prompt (bool): If True, prompt the user, or attempt to automatically save where possible
    """
    modified = pm.cmds.file(q=True, modified=True)
    neverSaved = not pm.sceneName()

    if neverSaved:
        # first time saving
        if not prompt:
            pm.runtime.SaveSceneAs()
            return bool(pm.sceneName())
        else:
            # either save as or cancel
            kwargs = dict(
                title='Warning: Scene Not Saved',
                message='Save changes to untitled scene?',
                db="Save", cb="Cancel", ds="Cancel",
                button=("Save", "Cancel"),
            )
            result = pm.confirmDialog(**kwargs)
            if result == 'Save':
                pm.runtime.SaveSceneAs()
                return bool(pm.sceneName())
            else:
                return False

    elif modified:
        # saving modified file
        if not prompt:
            return pm.saveFile(force=True)
        else:
            kwargs = dict(
                title='Save Scene',
                message='Save changes to\n{0}'.format(pm.sceneName()),
                db="Save", cb="Cancel", ds="Cancel",
                button=("Save", "Cancel"),
            )
            result = pm.confirmDialog(**kwargs)
            if result == 'Save':
                return pm.saveFile(force=True)
            else:
                return False

    else:
        return True

def getEditorBlueprint():
    """
    Return the shared Blueprint instance from the default UI model
    """
    import pulse.views
    return pulse.views.BlueprintUIModel.getDefaultModel().blueprint

def getSelectedTransforms(includeChildren=False):
    """
    Return the currently selected transforms (or joints).

    Args:
        includeChildren (bool): If true, also include all descendants
            if the selected nodes
    """
    sel = pm.selected(type=['transform', 'joint'])
    if includeChildren:
        result = []
        for s in sel:
            if s not in result:
                result.append(s)
            for child in s.listRelatives(ad=True, type=['transform', 'joint']):
                if child not in result:
                    result.append(child)
        return result
    else:
        return sel

def centerSelectedJoints():
    """
    Center the selected joint
    """
    for s in pm.selected():
        centerJoint(s)

def disableSegmentScaleCompensateForSelected():
    """
    Disable segment scale compensation on the selected joints
    """
    for jnt in pm.selected():
        if jnt.nodeType() == 'joint':
            jnt.ssc.set(False)

def insertJointForSelected(count=1):
    """
    Insert joints above the selected joint
    """
    result = []
    for s in pm.selected():
        result.extend(insertJoints(s, count))
    pm.select(result)

def createOffsetForSelected():
    """
    Create an offset group for the selected nodes
    """
    pm.select([createOffsetTransform(s)
               for s in pm.selected(type='transform')])

def freezeScalesForSelectedHierarchies():
    """
    Freeze scales on the selected transforms and all their descendants.
    See `freezeScalesForHierarchy` for more details.
    """
    with preservedSelection() as sel:
        tops = getParentNodes(sel[:])
        for t in tops:
            freezeScalesForHierarchy(t)

def freezePivotsForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            freezePivotsForHierarchy(s)

def freezeOffsetMatricesForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            freezeOffsetMatrixForHierarchy(s)

def unfreezeOffsetMatricesForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            unfreezeOffsetMatrixForHierarchy(s)

def parentSelected():
    """
    Parent the selected nodes. Select a leader then followers.

    [A, B, C] -> A|B, A|C
    """
    sel = pm.selected()
    if len(sel) < 2:
        pm.warning('More that one node must be selected')
        return
    setParent(sel[1:], sel[0])
    pm.select(sel)

def parentSelectedInOrder():
    """
    Parent the selected nodes to each other in order.
    Select from top of hierarchy downward, eg. [A, B, C] -> A|B|C
    """
    with preservedSelection() as sel:
        parentInOrder(sel[:])

def rotateSelectedComponentsAroundAxis(axis, degrees=90):
    """
    Rotate the components of a shape by 90 degrees along one axis

    Args:
        axis: A int representing which axis to rotate around
            X = 0, Y = 1, Z = 2
        degrees: A float, how many degrees to rotate the components on that axis
            default is 90
    """
    rotation = pm.dt.Vector()
    rotation[axis] = degrees
    for node in pm.selected():
        for shape in node.getShapes():
            rotateComponents(shape, rotation)

def orientToWorldForSelected(
        includeChildren=False,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Orient the selected joints or transforms to match
    the world aligned axes
    """
    # TODO: implement preserveShapes
    sel = getSelectedTransforms(includeChildren)
    for node in sel:
        if node.nodeType() == 'joint':
            orientJointToWorld(node)
            if syncJointAxes:
                matchJointRotationToOrient(node, preserveChildren)
        else:
            pm.rotate(node, (0, 0, 0), a=True, ws=True, pcp=preserveChildren)

def orientToJointForSelected(
        axisOrder,
        upAxisStr,
        includeChildren=False,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    """
    sel = getSelectedTransforms(includeChildren)
    for node in sel:
        if node.nodeType() == 'joint':
            orientJoint(node, axisOrder, upAxisStr)
            # if syncJointAxes:
            #     matchJointRotationToOrient(node, preserveChildren)

def rotateSelectedOrientsAroundAxis(
        axis, degrees=90,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Rotate the selected nodes around the given axis
    If the node is a joint, its jointOrient will be rotated

    Args:
        axis:
        degress:
        preserveChildren:
        preserveShapes:
        syncJointAxes (bool): If True, joints will also have their
            translate and scale axes updated to match the new orientation
    """
    # if currently on move tool, make sure its object space
    if pm.currentCtx() == pm.melGlobals['$gMove']:
        pm.manipMoveContext('Move', e=True, mode=0)

    rotation = pm.dt.Vector()
    rotation[axis] = degrees

    nodes = pm.selected()
    for node in nodes:
        rotateOrientOrTransform(
            node, rotation,
            preserveChildren, preserveShapes, syncJointAxes)

def rotateOrientOrTransform(
        node, rotation,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Rotate a node in local space, or if its a joint, by
    modifying the joint orient. Additionally, can preserve
    child transform positions and/or shapes (such as control cvs).

    Args:
        node:
        rotation:
        preserveChildren:
        preserveShapes:
        syncJointAxes (bool): If True, joints will also have their
            translate and scale axes updated to match the new orientation
    """
    if node.nodeType() == 'joint':
        rotateJointOrient(node, rotation)
        if syncJointAxes:
            matchJointRotationToOrient(node, preserveChildren)
    else:
        pm.rotate(node, rotation, os=True, r=True, pcp=preserveChildren)

        # normalize eulers to 0..360, assumed as part of orienting
        normalizeEulerRotations(node)

        if preserveShapes:
            shapes = node.getShapes()
            for shape in shapes:
                rotateComponents(shape, -rotation)

def interactiveOrientForSelected():
    sel = pm.selected(type='joint')
    rotateAxes = [s.rotateAxis for s in sel]
    pm.select(rotateAxes)

def fixupJointOrientForSelected(aimAxis="x", keepAxis="y", preserveChildren=True):
    sel = pm.selected(type='joint')
    for node in sel:
        fixupJointOrient(node, aimAxis=aimAxis, keepAxis=keepAxis,
                         preserveChildren=preserveChildren)

def matchJointRotationToOrientForSelected(preserveChildren=True):
    sel = pm.selected(type='joint')
    for node in sel:
        matchJointRotationToOrient(node, preserveChildren)

def getDetailedChannelBoxAttrs(node):
    """
    Return the list of attributes that are included
    when the 'detailed channel box' is enabled for a node.
    """
    attrs = [
        # rotate order
        'ro',
        # rotate axis
        'rax', 'ray', 'raz',
        # rotate pivot
        'rpx', 'rpy', 'rpz',
        # scale pivot
        'spx', 'spy', 'spz',
        # rotate pivot translate
        'rptx', 'rpty', 'rptz',
        # scale pivot translate
        'sptx', 'spty', 'sptz',
    ]

    if node.nodeType() == 'joint':
        attrs += [
            # joint orient
            'jox', 'joy', 'joz',
        ]

    return attrs

def isDetailedChannelBoxEnabled(node):
    def isVisibleInCB(node, attr):
        return cmds.getAttr(node + '.' + attr, cb=True)

    attrs = getDetailedChannelBoxAttrs(node)
    if any([isVisibleInCB(node, a) for a in attrs]):
        return True

def setDetailedChannelBoxEnabled(node, enabled=True):
    """
    Set whether a node should display detailed channel box
    attributes related to transforms and joint orients.
    """
    attrs = getDetailedChannelBoxAttrs(node)
    for attr in attrs:
        pm.cmds.setAttr(node + '.' + attr, cb=enabled)

def toggleDetailedChannelBoxForSelected():
    """
    Toggle the display of detailed channel box attributes
    for all selected nodes.
    """
    sel = pm.selected()

    isEnabled = False
    for s in sel:
        if isDetailedChannelBoxEnabled(s):
            isEnabled = True
            break

    for s in sel:
        setDetailedChannelBoxEnabled(s, not isEnabled)

def toggleLocalRotationAxesForSelected(includeChildren=False):
    sel = getSelectedTransforms(includeChildren)
    isEnabled = False
    for s in sel:
        if s.dla.get():
            isEnabled = True
            break

    for s in sel:
        s.dla.set(not isEnabled)

def linkSelected():
    sel = pm.selected()
    if len(sel) != 2:
        LOG.warning("Select a leader then a follower")
        return

    pulse.links.link(sel[0], sel[1])

def unlinkSelected():
    for s in pm.selected():
        pulse.links.unlink(s)

def snapToLinkForSelected():
    sel = pm.selected()
    if not sel:
        sel = pulse.links.getAllLinkedNodes()
        # TODO: sort by parenting hierarchy

    for node in sel:
        pulse.links.snapToLink(node)

def pairSelected():
    sel = pm.selected()
    if len(sel) == 2:
        pairMirrorNodes(sel[0], sel[1])

def unpairSelected():
    for s in pm.selected():
        unpairMirrorNode(s)

def mirrorSelected(
        recursive=True,
        create=True,
        curveShapes=True,
        links=True,
        reparent=True,
        transform=True,
        appearance=True):
    """
    Perform a mirroring operation on the selected nodes.

    Args:
        recursive (bool): Mirror the selected nodes and all children
        create (bool): Allow creation of new nodes if a pair is not found
        curveShapes (bool): Flip curve shapes of newly created nodes
        links (bool): Mirror links. See links.py
        reparent (bool): Mirror the parenting structure of the nodes
        transform (bool): Mirror the transform matrices of the nodes
        appearance (bool): Mirror the name and color of the nodes
    """
    nodes = pm.selected()
    if not nodes:
        LOG.warning("Select at least one node to mirror")
        return

    util = MirrorUtil()
    util.isRecursive = recursive
    util.isCreationAllowed = create

    if curveShapes:
        util.addOperation(MirrorCurveShapes())
    if links:
        util.addOperation(MirrorLinks())
    if reparent:
        util.addOperation(MirrorParenting())
    if transform:
        # TODO: configure the transform util with mirror mode, etc
        util.addOperation(MirrorTransforms())
    if appearance:
        blueprint = getEditorBlueprint()
        if blueprint:
            namesOp = MirrorNames()
            namesOp.blueprint = blueprint
            util.addOperation(namesOp)
            colorsOp = MirrorColors()
            colorsOp.blueprint = blueprint
            util.addOperation(colorsOp)
            jointDisplayOp = MirrorJointDisplay()
            util.addOperation(jointDisplayOp)

    util.run(nodes)

def saveSkinWeightsForSelected(filePath=None):
    """
    Save skin weights for the selected meshes to a file.

    Args:
        filePath (str): A full path to a .weights file to write. If None,
            will use the scene name.
    """
    if filePath is None:
        sceneName = pm.sceneName()
        if not sceneName:
            LOG.warning("Scene is not saved")
            return
        filePath = os.path.splitext(sceneName)[0] + '.weights'

    skins = [pulse.skins.getSkinFromMesh(m) for m in pm.selected()]
    skins = [s for s in skins if s]

    pulse.skins.saveSkinWeightsToFile(filePath, *skins)

def getNamedColor(name):
    """
    Return a color by name from the config of the editor Blueprint
    """
    blueprint = getEditorBlueprint()
    if blueprint:
        config = blueprint.getConfig()
        for color in config.get('colors', []):
            if color.get('name') == name:
                color = color.get('color')
                if color:
                    return colors.hexToRGB01(color)

def setOverrideColorForSelected(color):
    """
    Set the display override color for the selected nodes
    """
    for node in pm.selected():
        pulse.nodes.setOverrideColor(node, color)

def disableColorOverrideForSelected():
    for node in pm.selected():
        pulse.nodes.disableColorOverride(node)
<commit_msg>support selected rotateAxes when running Sync Axes<commit_after>"""
A function library of miscellaneous utils usually involving
editor selection or interactive work. Many UI commands are
located here, as they can be more specific than the core api
but still not dependent on a UI.
"""

import os
import logging
import maya.cmds as cmds
import pymel.core as pm

from pulse.vendor.mayacoretools import preservedSelection

from pulse.colors import *
from pulse.joints import *
from pulse.nodes import *
from pulse.shapes import *
from pulse.sym import *
import pulse.links
import pulse.skins

__all__ = [
    'centerSelectedJoints',
    'createOffsetForSelected',
    'disableColorOverrideForSelected',
    'disableSegmentScaleCompensateForSelected',
    'freezeOffsetMatricesForSelectedHierarchies',
    'freezePivotsForSelectedHierarchies',
    'freezeScalesForSelectedHierarchies',
    'getDetailedChannelBoxAttrs',
    'getNamedColor',
    'getSelectedTransforms',
    'insertJointForSelected',
    'interactiveOrientForSelected',
    'isDetailedChannelBoxEnabled',
    'linkSelected',
    'matchJointRotationToOrientForSelected',
    'mirrorSelected',
    'orientToJointForSelected',
    'orientToWorldForSelected',
    'pairSelected',
    'parentSelected',
    'parentSelectedInOrder',
    'rotateSelectedComponentsAroundAxis',
    'rotateSelectedOrientsAroundAxis',
    'saveSceneIfDirty',
    'saveSkinWeightsForSelected',
    'setDetailedChannelBoxEnabled',
    'setOverrideColorForSelected',
    'snapToLinkForSelected',
    'toggleDetailedChannelBoxForSelected',
    'toggleLocalRotationAxesForSelected',
    'unfreezeOffsetMatricesForSelectedHierarchies',
    'unlinkSelected',
    'unpairSelected',
]

LOG = logging.getLogger(__name__)

def saveSceneIfDirty(prompt=True):
    """
    Prompt the user to save if the scene is modified, or has never been saved.

    Returns True if the save was successful, or the scene has not been modified.

    Args:
        prompt (bool): If True, prompt the user, or attempt to automatically save where possible
    """
    modified = pm.cmds.file(q=True, modified=True)
    neverSaved = not pm.sceneName()

    if neverSaved:
        # first time saving
        if not prompt:
            pm.runtime.SaveSceneAs()
            return bool(pm.sceneName())
        else:
            # either save as or cancel
            kwargs = dict(
                title='Warning: Scene Not Saved',
                message='Save changes to untitled scene?',
                db="Save", cb="Cancel", ds="Cancel",
                button=("Save", "Cancel"),
            )
            result = pm.confirmDialog(**kwargs)
            if result == 'Save':
                pm.runtime.SaveSceneAs()
                return bool(pm.sceneName())
            else:
                return False

    elif modified:
        # saving modified file
        if not prompt:
            return pm.saveFile(force=True)
        else:
            kwargs = dict(
                title='Save Scene',
                message='Save changes to\n{0}'.format(pm.sceneName()),
                db="Save", cb="Cancel", ds="Cancel",
                button=("Save", "Cancel"),
            )
            result = pm.confirmDialog(**kwargs)
            if result == 'Save':
                return pm.saveFile(force=True)
            else:
                return False

    else:
        return True

def getEditorBlueprint():
    """
    Return the shared Blueprint instance from the default UI model
    """
    import pulse.views
    return pulse.views.BlueprintUIModel.getDefaultModel().blueprint

def getSelectedTransforms(includeChildren=False):
    """
    Return the currently selected transforms (or joints).

    Args:
        includeChildren (bool): If true, also include all descendants
            if the selected nodes
    """
    sel = pm.selected(type=['transform', 'joint'])
    if includeChildren:
        result = []
        for s in sel:
            if s not in result:
                result.append(s)
            for child in s.listRelatives(ad=True, type=['transform', 'joint']):
                if child not in result:
                    result.append(child)
        return result
    else:
        return sel

def centerSelectedJoints():
    """
    Center the selected joint
    """
    for s in pm.selected():
        centerJoint(s)

def disableSegmentScaleCompensateForSelected():
    """
    Disable segment scale compensation on the selected joints
    """
    for jnt in pm.selected():
        if jnt.nodeType() == 'joint':
            jnt.ssc.set(False)

def insertJointForSelected(count=1):
    """
    Insert joints above the selected joint
    """
    result = []
    for s in pm.selected():
        result.extend(insertJoints(s, count))
    pm.select(result)

def createOffsetForSelected():
    """
    Create an offset group for the selected nodes
    """
    pm.select([createOffsetTransform(s)
               for s in pm.selected(type='transform')])

def freezeScalesForSelectedHierarchies():
    """
    Freeze scales on the selected transforms and all their descendants.
    See `freezeScalesForHierarchy` for more details.
    """
    with preservedSelection() as sel:
        tops = getParentNodes(sel[:])
        for t in tops:
            freezeScalesForHierarchy(t)

def freezePivotsForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            freezePivotsForHierarchy(s)

def freezeOffsetMatricesForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            freezeOffsetMatrixForHierarchy(s)

def unfreezeOffsetMatricesForSelectedHierarchies():
    with preservedSelection() as sel:
        for s in sel:
            unfreezeOffsetMatrixForHierarchy(s)

def parentSelected():
    """
    Parent the selected nodes. Select a leader then followers.

    [A, B, C] -> A|B, A|C
    """
    sel = pm.selected()
    if len(sel) < 2:
        pm.warning('More that one node must be selected')
        return
    setParent(sel[1:], sel[0])
    pm.select(sel)

def parentSelectedInOrder():
    """
    Parent the selected nodes to each other in order.
    Select from top of hierarchy downward, eg. [A, B, C] -> A|B|C
    """
    with preservedSelection() as sel:
        parentInOrder(sel[:])

def rotateSelectedComponentsAroundAxis(axis, degrees=90):
    """
    Rotate the components of a shape by 90 degrees along one axis

    Args:
        axis: A int representing which axis to rotate around
            X = 0, Y = 1, Z = 2
        degrees: A float, how many degrees to rotate the components on that axis
            default is 90
    """
    rotation = pm.dt.Vector()
    rotation[axis] = degrees
    for node in pm.selected():
        for shape in node.getShapes():
            rotateComponents(shape, rotation)

def orientToWorldForSelected(
        includeChildren=False,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Orient the selected joints or transforms to match
    the world aligned axes
    """
    # TODO: implement preserveShapes
    sel = getSelectedTransforms(includeChildren)
    for node in sel:
        if node.nodeType() == 'joint':
            orientJointToWorld(node)
            if syncJointAxes:
                matchJointRotationToOrient(node, preserveChildren)
        else:
            pm.rotate(node, (0, 0, 0), a=True, ws=True, pcp=preserveChildren)

def orientToJointForSelected(
        axisOrder,
        upAxisStr,
        includeChildren=False,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    """
    sel = getSelectedTransforms(includeChildren)
    for node in sel:
        if node.nodeType() == 'joint':
            orientJoint(node, axisOrder, upAxisStr)
            # if syncJointAxes:
            #     matchJointRotationToOrient(node, preserveChildren)

def rotateSelectedOrientsAroundAxis(
        axis, degrees=90,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Rotate the selected nodes around the given axis
    If the node is a joint, its jointOrient will be rotated

    Args:
        axis:
        degress:
        preserveChildren:
        preserveShapes:
        syncJointAxes (bool): If True, joints will also have their
            translate and scale axes updated to match the new orientation
    """
    # if currently on move tool, make sure its object space
    if pm.currentCtx() == pm.melGlobals['$gMove']:
        pm.manipMoveContext('Move', e=True, mode=0)

    rotation = pm.dt.Vector()
    rotation[axis] = degrees

    nodes = pm.selected()
    for node in nodes:
        rotateOrientOrTransform(
            node, rotation,
            preserveChildren, preserveShapes, syncJointAxes)

def rotateOrientOrTransform(
        node, rotation,
        preserveChildren=True,
        preserveShapes=True,
        syncJointAxes=True):
    """
    Rotate a node in local space, or if its a joint, by
    modifying the joint orient. Additionally, can preserve
    child transform positions and/or shapes (such as control cvs).

    Args:
        node:
        rotation:
        preserveChildren:
        preserveShapes:
        syncJointAxes (bool): If True, joints will also have their
            translate and scale axes updated to match the new orientation
    """
    if node.nodeType() == 'joint':
        rotateJointOrient(node, rotation)
        if syncJointAxes:
            matchJointRotationToOrient(node, preserveChildren)
    else:
        pm.rotate(node, rotation, os=True, r=True, pcp=preserveChildren)

        # normalize eulers to 0..360, assumed as part of orienting
        normalizeEulerRotations(node)

        if preserveShapes:
            shapes = node.getShapes()
            for shape in shapes:
                rotateComponents(shape, -rotation)

def interactiveOrientForSelected():
    sel = pm.selected(type='joint')
    rotateAxes = [s.rotateAxis for s in sel]
    pm.select(rotateAxes)

def fixupJointOrientForSelected(aimAxis="x", keepAxis="y", preserveChildren=True):
    sel = pm.selected(type='joint')
    for node in sel:
        fixupJointOrient(node, aimAxis=aimAxis, keepAxis=keepAxis,
                         preserveChildren=preserveChildren)

def matchJointRotationToOrientForSelected(preserveChildren=True):
    # handle current selection containing both joints, and possibly pivots of joints
    sel = pm.selected()
    for s in sel:
        if s.nodeType() == 'joint':
            joint = s.node()
            matchJointRotationToOrient(joint, preserveChildren)

def getDetailedChannelBoxAttrs(node):
    """
    Return the list of attributes that are included
    when the 'detailed channel box' is enabled for a node.
    """
    attrs = [
        # rotate order
        'ro',
        # rotate axis
        'rax', 'ray', 'raz',
        # rotate pivot
        'rpx', 'rpy', 'rpz',
        # scale pivot
        'spx', 'spy', 'spz',
        # rotate pivot translate
        'rptx', 'rpty', 'rptz',
        # scale pivot translate
        'sptx', 'spty', 'sptz',
    ]

    if node.nodeType() == 'joint':
        attrs += [
            # joint orient
            'jox', 'joy', 'joz',
        ]

    return attrs

def isDetailedChannelBoxEnabled(node):
    def isVisibleInCB(node, attr):
        return cmds.getAttr(node + '.' + attr, cb=True)

    attrs = getDetailedChannelBoxAttrs(node)
    if any([isVisibleInCB(node, a) for a in attrs]):
        return True

def setDetailedChannelBoxEnabled(node, enabled=True):
    """
    Set whether a node should display detailed channel box
    attributes related to transforms and joint orients.
    """
    attrs = getDetailedChannelBoxAttrs(node)
    for attr in attrs:
        pm.cmds.setAttr(node + '.' + attr, cb=enabled)

def toggleDetailedChannelBoxForSelected():
    """
    Toggle the display of detailed channel box attributes
    for all selected nodes.
    """
    sel = pm.selected()

    isEnabled = False
    for s in sel:
        if isDetailedChannelBoxEnabled(s):
            isEnabled = True
            break

    for s in sel:
        setDetailedChannelBoxEnabled(s, not isEnabled)

def toggleLocalRotationAxesForSelected(includeChildren=False):
    sel = getSelectedTransforms(includeChildren)
    isEnabled = False
    for s in sel:
        if s.dla.get():
            isEnabled = True
            break

    for s in sel:
        s.dla.set(not isEnabled)

def linkSelected():
    sel = pm.selected()
    if len(sel) != 2:
        LOG.warning("Select a leader then a follower")
        return

    pulse.links.link(sel[0], sel[1])

def unlinkSelected():
    for s in pm.selected():
        pulse.links.unlink(s)

def snapToLinkForSelected():
    sel = pm.selected()
    if not sel:
        sel = pulse.links.getAllLinkedNodes()
        # TODO: sort by parenting hierarchy

    for node in sel:
        pulse.links.snapToLink(node)

def pairSelected():
    sel = pm.selected()
    if len(sel) == 2:
        pairMirrorNodes(sel[0], sel[1])

def unpairSelected():
    for s in pm.selected():
        unpairMirrorNode(s)

def mirrorSelected(
        recursive=True,
        create=True,
        curveShapes=True,
        links=True,
        reparent=True,
        transform=True,
        appearance=True):
    """
    Perform a mirroring operation on the selected nodes.

    Args:
        recursive (bool): Mirror the selected nodes and all children
        create (bool): Allow creation of new nodes if a pair is not found
        curveShapes (bool): Flip curve shapes of newly created nodes
        links (bool): Mirror links. See links.py
        reparent (bool): Mirror the parenting structure of the nodes
        transform (bool): Mirror the transform matrices of the nodes
        appearance (bool): Mirror the name and color of the nodes
    """
    nodes = pm.selected()
    if not nodes:
        LOG.warning("Select at least one node to mirror")
        return

    util = MirrorUtil()
    util.isRecursive = recursive
    util.isCreationAllowed = create

    if curveShapes:
        util.addOperation(MirrorCurveShapes())
    if links:
        util.addOperation(MirrorLinks())
    if reparent:
        util.addOperation(MirrorParenting())
    if transform:
        # TODO: configure the transform util with mirror mode, etc
        util.addOperation(MirrorTransforms())
    if appearance:
        blueprint = getEditorBlueprint()
        if blueprint:
            namesOp = MirrorNames()
            namesOp.blueprint = blueprint
            util.addOperation(namesOp)
            colorsOp = MirrorColors()
            colorsOp.blueprint = blueprint
            util.addOperation(colorsOp)
            jointDisplayOp = MirrorJointDisplay()
            util.addOperation(jointDisplayOp)

    util.run(nodes)

def saveSkinWeightsForSelected(filePath=None):
    """
    Save skin weights for the selected meshes to a file.

    Args:
        filePath (str): A full path to a .weights file to write. If None,
            will use the scene name.
    """
    if filePath is None:
        sceneName = pm.sceneName()
        if not sceneName:
            LOG.warning("Scene is not saved")
            return
        filePath = os.path.splitext(sceneName)[0] + '.weights'

    skins = [pulse.skins.getSkinFromMesh(m) for m in pm.selected()]
    skins = [s for s in skins if s]

    pulse.skins.saveSkinWeightsToFile(filePath, *skins)

def getNamedColor(name):
    """
    Return a color by name from the config of the editor Blueprint
    """
    blueprint = getEditorBlueprint()
    if blueprint:
        config = blueprint.getConfig()
        for color in config.get('colors', []):
            if color.get('name') == name:
                color = color.get('color')
                if color:
                    return colors.hexToRGB01(color)

def setOverrideColorForSelected(color):
    """
    Set the display override color for the selected nodes
    """
    for node in pm.selected():
        pulse.nodes.setOverrideColor(node, color)

def disableColorOverrideForSelected():
    for node in pm.selected():
        pulse.nodes.disableColorOverride(node)
<|endoftext|>


<commit_before>"""
@file
@brief Helpers for pip

Some links to look:

* `installing_python_packages_programatically.py <https://gist.github.com/rwilcox/755524>`_
* `Calling pip programmatically <http://blog.ducky.io/python/2013/08/22/calling-pip-programmatically/>`_
"""
import sys

class PQPipError (Exception):
    """
    any exception raised by one of the following function
    """

    def __init__(self, *l):
        """
        constructor

        @param      l   either a string 3 strings (cmd, out, err)
        """
        if len(l) == 1:
            Exception.__init__(self, l[0])
        else:
            cmd, out, err = l
            mes = "CMD:\n{0}\nOUT:\n{1}\n[piperror]\n{2}".format(cmd, out, err)
            Exception.__init__(self, mes)

def fix_pip_902():
    """
    Version 9.0.2 of pip introduced some weird checkings in file
    `pip/_vendor/requests/packages.py <https://github.com/pypa/pip/blob/master/src/pip/_vendor/requests/packages.py>`_.
    Option 1 is to avoid that version,
    option 2 is to try to fix it.

    @return     added keys in ``sys.modules``

    See blog post
    :ref:`pip 9.0.2 and issue with pip._vendor.urllib3.contrib <blog-pip-vendor-urllib3-contrib>`,
    the following code must be run before the error
    ``KeyError: 'pip._vendor.urllib3.contrib'`` is raised.

    ::

        from pyquickhelper.pycode.pip_helper import fix_pip_902
        fix_pip_902()
    """
    keys = ['pip._vendor.urllib3.contrib',
            'pip._vendor.urllib3.contrib.pyopenssl',
            'pip._vendor.urllib3.packages.backports',
            'pip._vendor.urllib3.packages.backports.makefile',
            'pip._vendor.urllib3.contrib.socks']
    res = []
    for key in keys:
        if key not in sys.modules:
            sys.modules[key] = None
            res.append(key)
    return set(res)

def get_packages_list():
    """
    calls ``pip list`` to retrieve the list of packages
    """
    try:
        # pip >= 10.0
        from pip._internal.utils.misc import get_installed_distributions
    except ImportError:
        # pip < 10.0
        from pip import get_installed_distributions
    return get_installed_distributions(local_only=True)

def package2dict(pkg):
    """
    extract information from a package

    @param      pkg     type *pip._vendor.pkg_resources.Distribution*
    @return             dictionary
    """
    return dict(
        version=pkg.version,
        project_name=pkg.project_name,
        py_version=pkg.py_version,
        requires=pkg.requires,
        platform=pkg.platform,
        extras=pkg.extras,
        location=pkg.location)

def get_package_info(name=None, start=0, end=-1):
    """
    calls ``pip show`` to retrieve information about packages

    @param      name        name of he packages or None to get all of them in a list
    @param      start       start at package n (in list return by @see fn get_packages_list)
    @param      end         end at package n, -1 for all
    @return                 dictionary or list of dictionaries
    """
    try:
        # pip >= 10.0
        from pip._internal.commands.show import search_packages_info
    except ImportError:
        # pip < 10.0
        from pip.commands.show import search_packages_info
    if name is None:
        res = []
        packs = get_packages_list()
        if end == -1:
            end = len(packs)
        subp = packs[start:end]
        if len(subp) == 0:
            raise PQPipError(
                "no package, start={0}, end={1}, len(subp)={2}, len(packs)={3}".format(start, end, len(subp), len(packs)))
        for cp in subp:
            pack = cp.project_name
            info = get_package_info(pack)
            res.append(info)
        if len(res) == 0 and len(subp) > 0:
            raise PQPipError(
                "empty list, unexpected, start={0}, end={1}, len(subp)={3}".format(start, end, len(subp)))
        return res
    else:
        res = [_ for _ in search_packages_info([name])]
        if len(res) != 1:
            raise PQPipError(
                "unexpected number of results {0} for {1}".format(len(res), name))
        return res[0]
<commit_msg>fix for pip >= 19.0<commit_after>"""
@file
@brief Helpers for pip

Some links to look:

* `installing_python_packages_programatically.py <https://gist.github.com/rwilcox/755524>`_
* `Calling pip programmatically <http://blog.ducky.io/python/2013/08/22/calling-pip-programmatically/>`_
"""
import sys
import pip.__main__ as pip_main

class PQPipError (Exception):
    """
    any exception raised by one of the following function
    """

    def __init__(self, *l):
        """
        constructor

        @param      l   either a string 3 strings (cmd, out, err)
        """
        if len(l) == 1:
            Exception.__init__(self, l[0])
        else:
            cmd, out, err = l
            mes = "CMD:\n{0}\nOUT:\n{1}\n[piperror]\n{2}".format(cmd, out, err)
            Exception.__init__(self, mes)

def fix_pip_902():
    """
    Version 9.0.2 of pip introduced some weird checkings in file
    `pip/_vendor/requests/packages.py <https://github.com/pypa/pip/blob/master/src/pip/_vendor/requests/packages.py>`_.
    Option 1 is to avoid that version,
    option 2 is to try to fix it.

    @return     added keys in ``sys.modules``

    See blog post
    :ref:`pip 9.0.2 and issue with pip._vendor.urllib3.contrib <blog-pip-vendor-urllib3-contrib>`,
    the following code must be run before the error
    ``KeyError: 'pip._vendor.urllib3.contrib'`` is raised.

    ::

        from pyquickhelper.pycode.pip_helper import fix_pip_902
        fix_pip_902()
    """
    keys = ['pip._vendor.urllib3.contrib',
            'pip._vendor.urllib3.contrib.pyopenssl',
            'pip._vendor.urllib3.packages.backports',
            'pip._vendor.urllib3.packages.backports.makefile',
            'pip._vendor.urllib3.contrib.socks']
    res = []
    for key in keys:
        if key not in sys.modules:
            sys.modules[key] = None
            res.append(key)
    return set(res)

def get_packages_list():
    """
    calls ``pip list`` to retrieve the list of packages
    """
    try:
        # pip >= 10.0
        from pip._internal.utils.misc import get_installed_distributions
    except ImportError:
        # pip < 10.0
        from pip import get_installed_distributions
    return get_installed_distributions(local_only=True)

def package2dict(pkg):
    """
    extract information from a package

    @param      pkg     type *pip._vendor.pkg_resources.Distribution*
    @return             dictionary
    """
    return dict(
        version=pkg.version,
        project_name=pkg.project_name,
        py_version=pkg.py_version,
        requires=pkg.requires,
        platform=pkg.platform,
        extras=pkg.extras,
        location=pkg.location)

def get_package_info(name=None, start=0, end=-1):
    """
    calls ``pip show`` to retrieve information about packages

    @param      name        name of he packages or None to get all of them in a list
    @param      start       start at package n (in list return by @see fn get_packages_list)
    @param      end         end at package n, -1 for all
    @return                 dictionary or list of dictionaries
    """
    try:
        # pip >= 10.0
        from pip._internal.commands.show import search_packages_info
    except ImportError:
        # pip < 10.0
        from pip.commands.show import search_packages_info
    if name is None:
        res = []
        packs = get_packages_list()
        if end == -1:
            end = len(packs)
        subp = packs[start:end]
        if len(subp) == 0:
            raise PQPipError(
                "no package, start={0}, end={1}, len(subp)={2}, len(packs)={3}".format(start, end, len(subp), len(packs)))
        for cp in subp:
            pack = cp.project_name
            info = get_package_info(pack)
            res.append(info)
        if len(res) == 0 and len(subp) > 0:
            raise PQPipError(
                "empty list, unexpected, start={0}, end={1}, len(subp)={3}".format(start, end, len(subp)))
        return res
    else:
        res = [_ for _ in search_packages_info([name])]
        if len(res) != 1:
            raise PQPipError(
                "unexpected number of results {0} for {1}".format(len(res), name))
        return res[0]
<|endoftext|>


<commit_before>import datetime

from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.utils.translation import ugettext as _

from .utils import nopermission, get_or_404

from ..forms import RegisterForm, DeregisterForm, HelperForm
from ..models import Event, Link
from ..permissions import has_access, ACCESS_INVOLVED

from news.helper import news_test_email

import logging
logger = logging.getLogger("helfertool")

def index_all_events(request):
    return index(request, False)

def index(request, filter_old_events=True):
    events = Event.objects.all()

    # public events
    active_events = [e for e in events if e.active]
    active_events = sorted(active_events, key=lambda e: e.date)

    # inactive events that are visible for current user
    involved_events = []
    enable_show_more_events = False
    if not request.user.is_anonymous:
        if filter_old_events:
            oldest_year = datetime.datetime.now().year - settings.EVENTS_LAST_YEARS
            filtered_events = events.filter(date__year__gte=oldest_year)
            enable_show_more_events = events.filter(date__year__lt=oldest_year).exists()
        else:
            filtered_events = events

        for event in filtered_events:
            event.involved = has_access(request.user, event, ACCESS_INVOLVED)

            if event.involved and not event.active:
                involved_events.append(event)

    # only one public event and no internal events -> redirect
    if events.count() == 1 and active_events:
        return redirect(form, event_url_name=active_events[0].url_name)

    context = {
        'active_events': active_events,
        'involved_events': involved_events,
        'enable_show_more_events': enable_show_more_events,
    }
    return render(request, 'registration/index.html', context)

def form(request, event_url_name, link_pk=None):
    event = get_object_or_404(Event, url_name=event_url_name)

    # get link if given
    link = None
    all_shifts = None
    if link_pk:
        try:
            link = Link.objects.get(pk=link_pk)
            all_shifts = link.shifts.all()
        except (Link.DoesNotExist, ValidationError):
            # show some message when link does not exist
            context = {'event': event}
            return render(request, 'registration/invalid_link.html', context)

        # check if link belongs to event
        if link.event != event:
            raise Http404()

    # check permission
    user_is_involved = has_access(request.user, event, ACCESS_INVOLVED)
    if not event.active and not link:
        # not logged in -> show message
        if not request.user.is_authenticated:
            # show some message when link does not exist
            context = {'event': event}
            return render(request, 'registration/not_active.html', context)
        # logged in -> check permission
        elif not user_is_involved:
            return nopermission(request)

    # handle form
    form = RegisterForm(request.POST or None, event=event, shifts=all_shifts,
                        link=link is not None)

    if form.is_valid():
        helper = form.save()

        logger.info("helper registered", extra={
            'event': event,
            'helper': helper,
            'withlink': link_pk is not None,
        })

        if not helper.send_mail(request, internal=False):
            messages.error(request, _("Sending the mail failed, but the registration was saved."))

        return HttpResponseRedirect(reverse('registered', args=[event.url_name, helper.pk]))

    context = {'event': event,
               'form': form,
               'user_is_involved': user_is_involved}
    return render(request, 'registration/form.html', context)

def registered(request, event_url_name, helper_id=None):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id,
                                           handle_duplicates=True)

    news = news_test_email(helper.email)

    context = {'event': event,
               'data': helper,
               'news': news}
    return render(request, 'registration/registered.html', context)

def validate(request, event_url_name, helper_id):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id,
                                           handle_duplicates=True)

    # 404 if validation is not used
    if not event.mail_validation:
        raise Http404()

    # already validated?
    already_validated = helper.validated

    # validate
    helper.validated = True
    helper.save()

    logger.info("helper validated", extra={
        'event': event,
        'helper': helper,
    })

    context = {'event': event,
               'already_validated': already_validated}
    return render(request, 'registration/validate.html', context)

def deregister(request, event_url_name, helper_id, shift_pk):
    event, job, shift, helper = get_or_404(event_url_name,
                                           helper_pk=helper_id,
                                           shift_pk=shift_pk)

    if not event.changes_possible:
        context = {'event': event}
        return render(request, 'registration/changes_not_possible.html',
                      context)

    form = DeregisterForm(request.POST or None, instance=helper, shift=shift)

    if form.is_valid():
        form.delete()

        logger.info("helper deregistered", extra={
            'event': event,
            'helper': helper,
            "helper_pk": helper_id,
        })

        if not helper.pk:
            return HttpResponseRedirect(reverse('deleted',
                                                args=[event.url_name]))

        return HttpResponseRedirect(reverse('registered',
                                            args=[event.url_name, helper.pk]))

    context = {'event': event,
               'helper': helper,
               'shift': shift,
               'form': form}
    return render(request, 'registration/deregister.html', context)

def deleted(request, event_url_name):
    event = get_object_or_404(Event, url_name=event_url_name)

    context = {'event': event}
    return render(request, 'registration/deleted.html', context)

def update_personal(request, event_url_name, helper_id):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id)

    if not event.changes_possible:
        context = {'event': event}
        return render(request, 'registration/changes_not_possible.html',
                      context)

    form = HelperForm(request.POST or None, instance=helper, event=event,
                      public=True)

    if form.is_valid():
        form.save()

        logger.info("helper dataupdated", extra={
            'event': event,
            'helper': helper,
            "helper_pk": helper_id,
        })

        if form.email_has_changed:
            if not helper.send_mail(request, internal=False):
                messages.error(request, _("Sending the mail failed, but the change was saved."))

        return HttpResponseRedirect(reverse('registered',
                                            args=[event.url_name, helper.pk]))

    news = news_test_email(helper.email)  # needed in template

    context = {'event': event,
               'data': helper,
               'news': news,
               'personal_data_form': form}
    return render(request, 'registration/registered.html', context)
<commit_msg>fixed bug: show "Display all events" only if more events appear<commit_after>import datetime

from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.utils.translation import ugettext as _

from .utils import nopermission, get_or_404

from ..forms import RegisterForm, DeregisterForm, HelperForm
from ..models import Event, Link
from ..permissions import has_access, ACCESS_INVOLVED

from news.helper import news_test_email

import logging
logger = logging.getLogger("helfertool")

def index_all_events(request):
    return index(request, False)

def index(request, filter_old_events=True):
    events = Event.objects.all()

    # public events
    active_events = [e for e in events if e.active]
    active_events = sorted(active_events, key=lambda e: e.date)

    # inactive events that are visible for current user
    involved_events = []
    enable_show_more_events = False
    if not request.user.is_anonymous:
        # first get all involved events
        all_involved_events = []
        for event in events:
            event.involved = has_access(request.user, event, ACCESS_INVOLVED)

            if event.involved and not event.active:
                all_involved_events.append(event)

        # and then optionally cut away the old ones
        if filter_old_events:
            oldest_year = datetime.datetime.now().year - settings.EVENTS_LAST_YEARS
            for event in all_involved_events:
                if event.date.year >= oldest_year:
                    involved_events.append(event)
                else:
                    # we skip an event, so we need a button to show it
                    enable_show_more_events = True
        else:
            involved_events = all_involved_events

    # only one public event and no internal events -> redirect
    if events.count() == 1 and active_events:
        return redirect(form, event_url_name=active_events[0].url_name)

    context = {
        'active_events': active_events,
        'involved_events': involved_events,
        'enable_show_more_events': enable_show_more_events,
    }
    return render(request, 'registration/index.html', context)

def form(request, event_url_name, link_pk=None):
    event = get_object_or_404(Event, url_name=event_url_name)

    # get link if given
    link = None
    all_shifts = None
    if link_pk:
        try:
            link = Link.objects.get(pk=link_pk)
            all_shifts = link.shifts.all()
        except (Link.DoesNotExist, ValidationError):
            # show some message when link does not exist
            context = {'event': event}
            return render(request, 'registration/invalid_link.html', context)

        # check if link belongs to event
        if link.event != event:
            raise Http404()

    # check permission
    user_is_involved = has_access(request.user, event, ACCESS_INVOLVED)
    if not event.active and not link:
        # not logged in -> show message
        if not request.user.is_authenticated:
            # show some message when link does not exist
            context = {'event': event}
            return render(request, 'registration/not_active.html', context)
        # logged in -> check permission
        elif not user_is_involved:
            return nopermission(request)

    # handle form
    form = RegisterForm(request.POST or None, event=event, shifts=all_shifts,
                        link=link is not None)

    if form.is_valid():
        helper = form.save()

        logger.info("helper registered", extra={
            'event': event,
            'helper': helper,
            'withlink': link_pk is not None,
        })

        if not helper.send_mail(request, internal=False):
            messages.error(request, _("Sending the mail failed, but the registration was saved."))

        return HttpResponseRedirect(reverse('registered', args=[event.url_name, helper.pk]))

    context = {'event': event,
               'form': form,
               'user_is_involved': user_is_involved}
    return render(request, 'registration/form.html', context)

def registered(request, event_url_name, helper_id=None):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id,
                                           handle_duplicates=True)

    news = news_test_email(helper.email)

    context = {'event': event,
               'data': helper,
               'news': news}
    return render(request, 'registration/registered.html', context)

def validate(request, event_url_name, helper_id):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id,
                                           handle_duplicates=True)

    # 404 if validation is not used
    if not event.mail_validation:
        raise Http404()

    # already validated?
    already_validated = helper.validated

    # validate
    helper.validated = True
    helper.save()

    logger.info("helper validated", extra={
        'event': event,
        'helper': helper,
    })

    context = {'event': event,
               'already_validated': already_validated}
    return render(request, 'registration/validate.html', context)

def deregister(request, event_url_name, helper_id, shift_pk):
    event, job, shift, helper = get_or_404(event_url_name,
                                           helper_pk=helper_id,
                                           shift_pk=shift_pk)

    if not event.changes_possible:
        context = {'event': event}
        return render(request, 'registration/changes_not_possible.html',
                      context)

    form = DeregisterForm(request.POST or None, instance=helper, shift=shift)

    if form.is_valid():
        form.delete()

        logger.info("helper deregistered", extra={
            'event': event,
            'helper': helper,
            "helper_pk": helper_id,
        })

        if not helper.pk:
            return HttpResponseRedirect(reverse('deleted',
                                                args=[event.url_name]))

        return HttpResponseRedirect(reverse('registered',
                                            args=[event.url_name, helper.pk]))

    context = {'event': event,
               'helper': helper,
               'shift': shift,
               'form': form}
    return render(request, 'registration/deregister.html', context)

def deleted(request, event_url_name):
    event = get_object_or_404(Event, url_name=event_url_name)

    context = {'event': event}
    return render(request, 'registration/deleted.html', context)

def update_personal(request, event_url_name, helper_id):
    event, job, shift, helper = get_or_404(event_url_name, helper_pk=helper_id)

    if not event.changes_possible:
        context = {'event': event}
        return render(request, 'registration/changes_not_possible.html',
                      context)

    form = HelperForm(request.POST or None, instance=helper, event=event,
                      public=True)

    if form.is_valid():
        form.save()

        logger.info("helper dataupdated", extra={
            'event': event,
            'helper': helper,
            "helper_pk": helper_id,
        })

        if form.email_has_changed:
            if not helper.send_mail(request, internal=False):
                messages.error(request, _("Sending the mail failed, but the change was saved."))

        return HttpResponseRedirect(reverse('registered',
                                            args=[event.url_name, helper.pk]))

    news = news_test_email(helper.email)  # needed in template

    context = {'event': event,
               'data': helper,
               'news': news,
               'personal_data_form': form}
    return render(request, 'registration/registered.html', context)
<|endoftext|>


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

class FileWriter(object):
    """Class for writing site files."""

    def get_canonical_filename(self, name):
        """Get file name from given path or file.

        If name is not recognized as a file name a /index.html is added.
        Leading slashes are stripped off.
        """

        if not name.startswith('/'):
            name = '/%s' % name

        if not os.path.splitext(name)[1]:
            name = os.path.join(name, 'index.html')

        return name.lstrip('/')

    def getfile(self, dir_dst, path):
        """Determine file to create and return an open file handle for writing.

        Paths pointing to a file name will be created as they are. When a path points
        to a directory a file named index.html will be created in that directory.
        """

        filename = self.get_canonical_filename(path)

        # create target directory if it doesn't exist
        dir_target = os.path.join(dir_dst, os.path.dirname(filename))
        if not os.path.exists(dir_target):
            os.makedirs(dir_target)

        return open(os.path.join(dir_dst, filename), 'w')

    def write(self, file, content):
        """Write content to file and close it."""

        file.write(content)
        file.close()

class DocWriter(FileWriter):
    """Class for writing site documents."""

    def __init__(self, dir_dst, template):
        """Set required properties."""

        self.dir_dst = dir_dst
        self.template = template

    def set_template_vars(self, doc):
        """Set template variables."""

        for field, val in doc.items():
            if isinstance(val, str):
                val = val.decode('utf-8')
            self.template.add_var(field, val)

    def write(self, doc, template):
        """Render and write document to created file.

        Returns False if template is False.
        """

        if not template:
            return False

        self.set_template_vars(doc)
        page = self.template.get_env().get_template(template)

        file = self.getfile(self.dir_dst, doc['url'])
        file.write(page.render(self.template.get_vars()).encode('utf-8'))
        file.close()<commit_msg>renamed file to out<commit_after># -*- coding: utf-8 -*-
import os

class FileWriter(object):
    """Class for writing site files."""

    def get_canonical_filename(self, name):
        """Get file name from given path or file.

        If name is not recognized as a file name a /index.html is added.
        Leading slashes are stripped off.
        """

        if not name.startswith('/'):
            name = '/%s' % name

        if not os.path.splitext(name)[1]:
            name = os.path.join(name, 'index.html')

        return name.lstrip('/')

    def getfile(self, dir_dst, path):
        """Determine file to create and return an open file handle for writing.

        Paths pointing to a file name will be created as they are. When a path points
        to a directory a file named index.html will be created in that directory.
        """

        filename = self.get_canonical_filename(path)

        # create target directory if it doesn't exist
        dir_target = os.path.join(dir_dst, os.path.dirname(filename))
        if not os.path.exists(dir_target):
            os.makedirs(dir_target)

        return open(os.path.join(dir_dst, filename), 'w')

    def write(self, file, content):
        """Write content to file and close it."""

        file.write(content)
        file.close()

class DocWriter(FileWriter):
    """Class for writing site documents."""

    def __init__(self, dir_dst, template):
        """Set required properties."""

        self.dir_dst = dir_dst
        self.template = template

    def set_template_vars(self, doc):
        """Set template variables."""

        for field, val in doc.items():
            if isinstance(val, str):
                val = val.decode('utf-8')
            self.template.add_var(field, val)

    def write(self, doc, template):
        """Render and write document to created file.

        Returns False if template is False.
        """

        if not template:
            return False

        self.set_template_vars(doc)
        page = self.template.get_env().get_template(template)

        out = self.getfile(self.dir_dst, doc['url'])
        out.write(page.render(self.template.get_vars()).encode('utf-8'))
        out.close()<|endoftext|>


<commit_before>from random import *

class Kind:
    def __init__(self, _nafn, _tyngd, _mjokl, _ull, _fjoldiafkvaema, _laeri, _frjosemi, _bakvodvi, _malir, _papi, _madre):
        self.nafn = _nafn
        self.tyngd = _tyngd
        self.mjokl = _mjokl
        self.ull = _ull
        self.afkvaemi = _fjoldiafkvaema
        self.laeri = _laeri
        self.frjosemi = _frjosemi
        self.bakvodvi = _bakvodvi
        self.malir = _malir
        self.papi = _papi
        self.madre = _madre

listi1 = []
listi2 = []

spil = []
with open("spilastokkur.txt", "r", encoding="utf-8") as f:
    for i in f.readlines():
        a = i.split(",")
        if "\n" in a[10]:
            a[10] = a[10].replace("\n", "")
        spil.append(Kind(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]))
print("Velkominn í örugglega leiðinlegasta leik sem þú munt nokkurn tíman spila.")

while True:
    print("Y O W H A T S U P J I M B O")
    spilararSpurning = int(input("Hversu margir eru að spila?" ))
    spilarar = []
    tel = 0
    for i in range(spilararSpurning):
        spilarar.append([])
    for i in range(500):
        if 52 - i >= spilararSpurning - tel:
            randomTala = randint(0,len(spil)-1)
            spilarar[tel].append(spil.pop(randomTala))
        else:
            break
        print(tel)
        if tel >= spilararSpurning-1:
            tel = 0
        else:
            tel += 1
    print("Nú hefst leikurinn!")
    while True:
        # prentar út spilið
        print("")<commit_msg>Hint: dab<commit_after>from random import *

class Kind:
    def __init__(self, _nafn, _tyngd, _mjokl, _ull, _fjoldiafkvaema, _laeri, _frjosemi, _bakvodvi, _malir, _papi, _madre):
        self.nafn = _nafn
        self.tyngd = _tyngd
        self.mjokl = _mjokl
        self.ull = _ull
        self.afkvaemi = _fjoldiafkvaema
        self.laeri = _laeri
        self.frjosemi = _frjosemi
        self.bakvodvi = _bakvodvi
        self.malir = _malir
        self.papi = _papi
        self.madre = _madre
        self.listi = [_tyngd, _mjokl, _ull, _fjoldiafkvaema, _laeri, _frjosemi, _bakvodvi, _malir]

def PrentaSpil(_spilari):
    print("xd rawr")

spilarar = []

def Deal(_spilarar):
    tel = 0
    for i in range(spilararSpurning):
        spilarar.append([])
    for i in range(500):
        if 52 - i >= spilararSpurning - tel:
            randomTala = randint(0, len(spil) - 1)
            spilarar[tel].append(spil.pop(randomTala))
        else:
            break
        print(tel)
        if tel >= spilararSpurning - 1:
            tel = 0
        else:
            tel += 1

def Turn(_spilari, _numerADoti):
    sigurvegari = gera
    _numerADoti-=1
    afgangur = []
    for i in range(len(spilarar)):
        if _spilari.listi[_numerADoti] < spilarar[i][0].listi[_numerADoti]:
            sigurvegari = i
        elif _spilari.listi[_numerADoti] == spilarar[i][0].listi[_numerADoti]:
            afgangur.append()#dabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdabdab

spil = []
with open("spilastokkur.txt", "r", encoding="utf-8") as f:
    for i in f.readlines():
        a = i.split(",")
        if "\n" in a[10]:
            a[10] = a[10].replace("\n", "")
        spil.append(Kind(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]))
print("Velkominn í örugglega leiðinlegasta leik sem þú munt nokkurn tíman spila.")

gera = 0

while True:
    print("Y O W H A T S U P J I M B O")
    spilararSpurning = int(input("Hversu margir eru að spila?" ))
    Deal(spilararSpurning)
    print("Nú hefst leikurinn!")
    while True:
        numerADotiTilAdNotaTilTessAdBeraSamanVidOnnurDotHjaOdrumSpilurum = input("Hvað viltu gera? ")
        Turn(spilarar[gera], numerADotiTilAdNotaTilTessAdBeraSamanVidOnnurDotHjaOdrumSpilurum)
        print("")
<|endoftext|>


<commit_before>#! /usr/bin/env python
"""
Group fMRI analysis frontend for Lyman ecosystem

"""
import os
import sys
import time
import shutil
import os.path as op

import matplotlib as mpl
mpl.use("Agg")
from nipype.pipeline.engine import Node, MapNode
from nipype.interfaces.io import DataGrabber, DataSink
from nipype.interfaces.utility import IdentityInterface

import lyman.workflows as wf
from lyman import tools
from lyman.tools.commandline import parser

def main(arglist):
    """Main function for workflow setup and execution."""
    args = parse_args(arglist)

    # Get and process specific information
    project = tools.gather_project_info()
    exp = tools.gather_experiment_info(args.experiment, args.altmodel)

    if args.altmodel:
        exp_name = "-".join([args.experiment, args.altmodel])
    else:
        exp_name = args.experiment

    # Make sure some paths are set properly
    os.environ["SUBJECTS_DIR"] = project["data_dir"]
    script_dir = os.path.abspath(".")
    sys.path.insert(0, script_dir)
    if "PYTHONPATH" in os.environ:
        os.environ["PYTHONPATH"] = "%s:%s" % (script_dir,
                                              os.environ["PYTHONPATH"])
    else:
        os.environ["PYTHONPATH"] = "%s" % script_dir

    # Set roots of output storage
    anal_dir_base = op.join(project["analysis_dir"], exp_name)
    work_dir_base = op.join(project["working_dir"], exp_name)
    crashdump_dir = "/tmp/%d" % time.time()

    # Subject source (no iterables here)
    subject_list = tools.determine_subjects(args.subjects)
    subj_source = Node(IdentityInterface(fields=["subject_id"]),
                       name="subj_source")
    subj_source.inputs.subject_id = subject_list

    # Set up the regressors and contrasts
    regressors = dict(group_mean=[1] * len(subject_list))
    contrasts = [["group_mean", "T", ["group_mean"], [1]]]

    # Subject level contrast source
    contrast_source = Node(IdentityInterface(fields=["l1_contrast"]),
                           iterables=("l1_contrast", exp["contrast_names"]),
                           name="contrast_source")

    # Mixed effects group workflow
    mfx, mfx_input, mfx_output = wf.create_volume_mixedfx_workflow(
        subject_list=subject_list, regressors=regressors, contrasts=contrasts)

    # Mixed effects inputs
    mfx_template = "%s/ffx/" + args.regspace + "/smoothed/%s/%s1.nii.gz"
    mfx_source = MapNode(DataGrabber(infields=["subject_id",
                                               "l1_contrast"],
                                     outfields=["copes", "varcopes", "dofs"],
                                     base_directory=anal_dir_base,
                                     template=mfx_template,
                                     sort_filelist=True),
                      iterfield=["subject_id"],
                      name="mfx_source")
    mfx_source.inputs.template_args = dict(
        copes=[["subject_id", "l1_contrast", "cope"]],
        varcopes=[["subject_id", "l1_contrast", "varcope"]],
        dofs=[["subject_id", "l1_contrast", "tdof_t"]])

    mfx.connect([
        (contrast_source, mfx_source,
            [("l1_contrast", "l1_contrast")]),
        (contrast_source, mfx_input,
            [("l1_contrast", "l1_contrast")]),
        (subj_source, mfx_source,
            [("subject_id", "subject_id")]),
        (mfx_source, mfx_input,
            [("copes", "copes"),
             ("varcopes", "varcopes"),
             ("dofs", "dofs")]),
             ])

    # Mixed effects outputs
    mfx_sink = Node(DataSink(base_directory="%s/group/%s/" % (anal_dir_base,
                                                              args.regspace),
                             substitutions=[("/stats", "/")],
                             parameterization=False),
                    name="mfx_sink")

    mfx_outwrap = tools.OutputWrapper(mfx, subj_source,
                                      mfx_sink, mfx_output)
    mfx_outwrap.sink_outputs()
    mfx.connect(contrast_source, "l1_contrast",
                mfx_sink, "container")

    # Set a few last things
    mfx.base_dir = work_dir_base
    tools.crashdump_config(mfx, crashdump_dir)

    # Execute
    tools.run_workflow(mfx, args=args)

    # Clean up
    if project["rm_working_dir"]:
        shutil.rmtree(project["working_dir"])

def parse_args(arglist):
    """Take an arglist and return an argparse Namespace."""
    parser.add_argument("-experiment", help="experimental paradigm")
    parser.add_argument("-altmodel", help="alternate model to fit")
    parser.add_argument("-regspace", default="mni",
                        choices=wf.spaces,
                        help="common space for registration and fixed effects")
    return parser.parse_args(arglist)

if __name__ == "__main__":
    main(sys.argv[1:])
<commit_msg>edited path directories for dof files<commit_after>#! /usr/bin/env python
"""
Group fMRI analysis frontend for Lyman ecosystem

"""
import os
import sys
import time
import shutil
import os.path as op

import matplotlib as mpl
mpl.use("Agg")
from nipype.pipeline.engine import Node, MapNode
from nipype.interfaces.io import DataGrabber, DataSink
from nipype.interfaces.utility import IdentityInterface

import lyman.workflows as wf
from lyman import tools
from lyman.tools.commandline import parser

def main(arglist):
    """Main function for workflow setup and execution."""
    args = parse_args(arglist)

    # Get and process specific information
    project = tools.gather_project_info()
    exp = tools.gather_experiment_info(args.experiment, args.altmodel)

    if args.altmodel:
        exp_name = "-".join([args.experiment, args.altmodel])
    else:
        exp_name = args.experiment

    # Make sure some paths are set properly
    os.environ["SUBJECTS_DIR"] = project["data_dir"]
    script_dir = os.path.abspath(".")
    sys.path.insert(0, script_dir)
    if "PYTHONPATH" in os.environ:
        os.environ["PYTHONPATH"] = "%s:%s" % (script_dir,
                                              os.environ["PYTHONPATH"])
    else:
        os.environ["PYTHONPATH"] = "%s" % script_dir

    # Set roots of output storage
    anal_dir_base = op.join(project["analysis_dir"], exp_name)
    work_dir_base = op.join(project["working_dir"], exp_name)
    crashdump_dir = "/tmp/%d" % time.time()

    # Subject source (no iterables here)
    subject_list = tools.determine_subjects(args.subjects)
    subj_source = Node(IdentityInterface(fields=["subject_id"]),
                       name="subj_source")
    subj_source.inputs.subject_id = subject_list

    # Set up the regressors and contrasts
    regressors = dict(group_mean=[1] * len(subject_list))
    contrasts = [["group_mean", "T", ["group_mean"], [1]]]

    # Subject level contrast source
    contrast_source = Node(IdentityInterface(fields=["l1_contrast"]),
                           iterables=("l1_contrast", exp["contrast_names"]),
                           name="contrast_source")

    # Mixed effects group workflow
    mfx, mfx_input, mfx_output = wf.create_volume_mixedfx_workflow(
        subject_list=subject_list, regressors=regressors, contrasts=contrasts)

    # Mixed effects inputs
    mfx_template = "%s/ffx/" + args.regspace + "/smoothed/%s/stats/%s1.nii.gz"
    mfx_source = MapNode(DataGrabber(infields=["subject_id",
                                               "l1_contrast"],
                                     outfields=["copes", "varcopes", "dofs"],
                                     base_directory=anal_dir_base,
                                     template=mfx_template,
                                     sort_filelist=True),
                      iterfield=["subject_id"],
                      name="mfx_source")
    mfx_source.inputs.template_args = dict(
        copes=[["subject_id", "l1_contrast", "cope"]],
        varcopes=[["subject_id", "l1_contrast", "varcope"]],
        dofs=[["subject_id", "l1_contrast", "tdof_t"]])

    mfx.connect([
        (contrast_source, mfx_source,
            [("l1_contrast", "l1_contrast")]),
        (contrast_source, mfx_input,
            [("l1_contrast", "l1_contrast")]),
        (subj_source, mfx_source,
            [("subject_id", "subject_id")]),
        (mfx_source, mfx_input,
            [("copes", "copes"),
             ("varcopes", "varcopes"),
             ("dofs", "dofs")]),
             ])

    # Mixed effects outputs
    mfx_sink = Node(DataSink(base_directory="%s/group/%s/" % (anal_dir_base,
                                                              args.regspace),
                             substitutions=[("/stats", "/")],
                             parameterization=False),
                    name="mfx_sink")

    mfx_outwrap = tools.OutputWrapper(mfx, subj_source,
                                      mfx_sink, mfx_output)
    mfx_outwrap.sink_outputs()
    mfx.connect(contrast_source, "l1_contrast",
                mfx_sink, "container")

    # Set a few last things
    mfx.base_dir = work_dir_base
    tools.crashdump_config(mfx, crashdump_dir)

    # Execute
    tools.run_workflow(mfx, args=args)

    # Clean up
    if project["rm_working_dir"]:
        shutil.rmtree(project["working_dir"])

def parse_args(arglist):
    """Take an arglist and return an argparse Namespace."""
    parser.add_argument("-experiment", help="experimental paradigm")
    parser.add_argument("-altmodel", help="alternate model to fit")
    parser.add_argument("-regspace", default="mni",
                        choices=wf.spaces,
                        help="common space for registration and fixed effects")
    return parser.parse_args(arglist)

if __name__ == "__main__":
    main(sys.argv[1:])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##
##
## This file is part of Indico.
## Copyright (C) 2002 - 2014 European Organization for Nuclear Research (CERN).
##
## Indico 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.
##
## Indico 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 Indico;if not, see <http://www.gnu.org/licenses/>.

__all__ = ['DBMgr', 'MigratedDB']

import logging
import time

from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.engine import reflection, Engine
from sqlalchemy.event import listens_for
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.schema import (
    MetaData,
    Table,
    DropTable,
    ForeignKeyConstraint,
    DropConstraint,
)
from sqlalchemy.sql.expression import FunctionElement
from sqlalchemy.types import Numeric
from zope.sqlalchemy import ZopeTransactionExtension

from ..errors import IndicoError
from .manager import DBMgr
from .migration import MigratedDB

db = SQLAlchemy(session_options={'extension': ZopeTransactionExtension()})

def apply_db_loggers(debug=False):
    if debug:
        from indico.core.logger import Logger
        logger = Logger.get('db')
        logger.setLevel(logging.DEBUG)

        @listens_for(Engine, 'before_cursor_execute')
        def before_cursor_execute(conn, cursor, statement,
                                  parameters, context, executemany):
            context._query_start_time = time.time()
            logger.debug('Start Query: {}'.format(statement))

        @listens_for(Engine, 'after_cursor_execute')
        def after_cursor_execute(conn, cursor, statement,
                                 parameters, context, executemany):
            total = time.time() - context._query_start_time
            logger.debug('Query Complete!')
            logger.debug('Total Time: {}'.format(total))

class IndicoDBError(IndicoError):
    pass

class Committer(object):

    def __enter__(self):
        pass

    def __exit__(self, e_typ, e_val, trcbak):
        if e_typ:
            db.session.rollback()
        else:
            db.session.commit()

# ================================== time diff

# engine specific time differences
class time_diff(FunctionElement):
    name = 'time_diff'
    type = Numeric

@compiles(time_diff, 'default')
def _time_diff_default(element, compiler, **kwargs):
    arg1, arg2 = list(element.clauses)
    return '{} - {}'.format(arg2, arg1)

@compiles(time_diff, 'postgresql')
def _time_diff_postgres(element, compiler, **kwargs):
    arg1, arg2 = list(element.clauses)
    return 'EXTRACT(epoch FROM {}::time) - EXTRACT(epoch FROM {}::time)'.format(arg2, arg1)

# ================================ greatest

class greatest(FunctionElement):
    name = 'greatest'

@compiles(greatest)
def default_greatest(element, compiler, **kw):
    return compiler.visit_function(element)

@compiles(greatest, 'postgresql')
def case_greatest(element, compiler, **kw):
    arg1, arg2 = list(element.clauses)
    return 'CASE WHEN %s > %s THEN %s ELSE %s END' % (
        compiler.process(arg1),
        compiler.process(arg2),
        compiler.process(arg1),
        compiler.process(arg2),
    )

# ============================= least

class least(FunctionElement):
    name = 'least'

@compiles(least)
def default_least(element, compiler, **kw):
    return compiler.visit_function(element)

@compiles(least, 'postgresql')
def case_least(element, compiler, **kw):
    arg1, arg2 = list(element.clauses)
    return 'CASE WHEN %s > %s THEN %s ELSE %s END' % (
        compiler.process(arg1),
        compiler.process(arg2),
        compiler.process(arg2),
        compiler.process(arg1),
    )

def drop_database(db):
    if db.engine.name == 'sqlite':
        db.drop_all()
    else:
        conn = db.engine.connect()
        trans = conn.begin()
        inspector = reflection.Inspector.from_engine(db.engine)

        metadata = MetaData()

        tbs, all_fks = [], []
        for table_name in inspector.get_table_names():
            fks = [ForeignKeyConstraint((), (), name=fk['name'])
                   for fk in inspector.get_foreign_keys(table_name)
                   if fk['name']]
            tbs.append(Table(table_name, metadata, *fks))
            all_fks.extend(fks)

        for fkc in all_fks:
            conn.execute(DropConstraint(fkc))
        for table in tbs:
            conn.execute(DropTable(table))
        trans.commit()
<commit_msg>[FIX] conditional transaction manager<commit_after># -*- coding: utf-8 -*-
##
##
## This file is part of Indico.
## Copyright (C) 2002 - 2014 European Organization for Nuclear Research (CERN).
##
## Indico 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.
##
## Indico 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 Indico;if not, see <http://www.gnu.org/licenses/>.

__all__ = ['DBMgr', 'MigratedDB']

import inspect
import logging
import time

from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.engine import reflection, Engine
from sqlalchemy.event import listens_for
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.schema import (
    MetaData,
    Table,
    DropTable,
    ForeignKeyConstraint,
    DropConstraint,
)
from sqlalchemy.sql.expression import FunctionElement
from sqlalchemy.types import Numeric
from zope.sqlalchemy import ZopeTransactionExtension

from ..errors import IndicoError
from .manager import DBMgr
from .migration import MigratedDB

if inspect.stack()[1][0].f_globals.get('__no_session_options__', False):
    db = SQLAlchemy()  # for testing and migration, manager isn't needed
else:
    db = SQLAlchemy(session_options={'extension': ZopeTransactionExtension()})

def apply_db_loggers(debug=False):
    if debug:
        from indico.core.logger import Logger
        logger = Logger.get('db')
        logger.setLevel(logging.DEBUG)

        @listens_for(Engine, 'before_cursor_execute')
        def before_cursor_execute(conn, cursor, statement,
                                  parameters, context, executemany):
            context._query_start_time = time.time()
            logger.debug('Start Query: {}'.format(statement))

        @listens_for(Engine, 'after_cursor_execute')
        def after_cursor_execute(conn, cursor, statement,
                                 parameters, context, executemany):
            total = time.time() - context._query_start_time
            logger.debug('Query Complete!')
            logger.debug('Total Time: {}'.format(total))

class IndicoDBError(IndicoError):
    pass

class Committer(object):

    def __enter__(self):
        pass

    def __exit__(self, e_typ, e_val, trcbak):
        if e_typ:
            db.session.rollback()
        else:
            db.session.commit()

# ================================== time diff

# engine specific time differences
class time_diff(FunctionElement):
    name = 'time_diff'
    type = Numeric

@compiles(time_diff, 'default')
def _time_diff_default(element, compiler, **kwargs):
    arg1, arg2 = list(element.clauses)
    return '{} - {}'.format(arg2, arg1)

@compiles(time_diff, 'postgresql')
def _time_diff_postgres(element, compiler, **kwargs):
    arg1, arg2 = list(element.clauses)
    return 'EXTRACT(epoch FROM {}::time) - EXTRACT(epoch FROM {}::time)'.format(arg2, arg1)

# ================================ greatest

class greatest(FunctionElement):
    name = 'greatest'

@compiles(greatest)
def default_greatest(element, compiler, **kw):
    return compiler.visit_function(element)

@compiles(greatest, 'postgresql')
def case_greatest(element, compiler, **kw):
    arg1, arg2 = list(element.clauses)
    return 'CASE WHEN %s > %s THEN %s ELSE %s END' % (
        compiler.process(arg1),
        compiler.process(arg2),
        compiler.process(arg1),
        compiler.process(arg2),
    )

# ============================= least

class least(FunctionElement):
    name = 'least'

@compiles(least)
def default_least(element, compiler, **kw):
    return compiler.visit_function(element)

@compiles(least, 'postgresql')
def case_least(element, compiler, **kw):
    arg1, arg2 = list(element.clauses)
    return 'CASE WHEN %s > %s THEN %s ELSE %s END' % (
        compiler.process(arg1),
        compiler.process(arg2),
        compiler.process(arg2),
        compiler.process(arg1),
    )

def drop_database(db):
    if db.engine.name == 'sqlite':
        db.drop_all()
    else:
        conn = db.engine.connect()
        trans = conn.begin()
        inspector = reflection.Inspector.from_engine(db.engine)

        metadata = MetaData()

        tbs, all_fks = [], []
        for table_name in inspector.get_table_names():
            fks = [ForeignKeyConstraint((), (), name=fk['name'])
                   for fk in inspector.get_foreign_keys(table_name)
                   if fk['name']]
            tbs.append(Table(table_name, metadata, *fks))
            all_fks.extend(fks)

        for fkc in all_fks:
            conn.execute(DropConstraint(fkc))
        for table in tbs:
            conn.execute(DropTable(table))
        trans.commit()
<|endoftext|>


<commit_before>from django.conf.urls import url
from django.urls import path, include, re_path
from django.contrib import admin
from django.views.generic import TemplateView
from django.conf import settings
from madrona.features.views import workspace
from django.views.static import serve
from trees.views import map
# admin.autodiscover()

urlpatterns = [
    # '',
    path('discovery/', include('discovery.urls')),
    re_path(r'^trees/', include('trees.urls')),
    # Looser pattern matching for workspace username (as opposed to \w+)
    # Already in madrona 4.2dev+ but just in case we're still running <=4.1
    re_path(r'^features/(?P<username>.+)/workspace-owner.json', workspace, kwargs={"is_owner": True}, name='workspace-owner-json'),
    re_path(r'^features/(?P<username>.+)/workspace-shared.json', workspace, kwargs={"is_owner": False}, name='workspace-shared-json'),

    re_path(r'^map/?$', map, name='map'),

    re_path(r'^auth/', include('allauth.urls')),
    re_path(
        r'^auth/profile/',
        TemplateView.as_view(template_name = 'account/profile.html'),
        name="auth_profile"
    ),
    re_path('admin/', admin.site.urls),
    re_path(r'^/?$', map, name='map'),
    re_path(r'^', include('madrona.common.urls')),
]

if settings.DEBUG:
    urlpatterns += [
        re_path(
            r'^media/(?P<path>.*)$',
            serve,
            kwargs={'document_root': settings.MEDIA_ROOT, 'show_indexes': True},
        ),
    ]
<commit_msg>default landing page is Discovery<commit_after>from django.conf.urls import url
from django.urls import path, include, re_path
from django.contrib import admin
from django.views.generic import TemplateView
from django.conf import settings
from madrona.features.views import workspace
from django.views.static import serve
from trees.views import map
# admin.autodiscover()

urlpatterns = [
    # '',
    path('discovery/', include('discovery.urls')),
    re_path(r'^trees/', include('trees.urls')),
    # Looser pattern matching for workspace username (as opposed to \w+)
    # Already in madrona 4.2dev+ but just in case we're still running <=4.1
    re_path(r'^features/(?P<username>.+)/workspace-owner.json', workspace, kwargs={"is_owner": True}, name='workspace-owner-json'),
    re_path(r'^features/(?P<username>.+)/workspace-shared.json', workspace, kwargs={"is_owner": False}, name='workspace-shared-json'),

    re_path(r'^map/?$', map, name='map'),

    re_path(r'^auth/', include('allauth.urls')),
    re_path(
        r'^auth/profile/',
        TemplateView.as_view(template_name = 'account/profile.html'),
        name="auth_profile"
    ),
    re_path('admin/', admin.site.urls),
    # re_path(r'^/?$', map, name='map'),
    re_path(r'^/?$', include('discovery.urls')),
    re_path(r'^', include('madrona.common.urls')),
]

if settings.DEBUG:
    urlpatterns += [
        re_path(
            r'^media/(?P<path>.*)$',
            serve,
            kwargs={'document_root': settings.MEDIA_ROOT, 'show_indexes': True},
        ),
    ]
<|endoftext|>


<commit_before><commit_msg>NEW: add option concat in command line<commit_after><|endoftext|>