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

import maya.OpenMaya as OpenMaya
import maya.cmds as cmds

import IECoreMaya
import IECore

def __getFloat3PlugValue(plug):

	# Retrieve the value as an MObject
	object = plug.asMObject()

	# Convert the MObject to a float3
	numDataFn = OpenMaya.MFnNumericData(object)
	xParam = OpenMaya.MScriptUtil()
	xParam.createFromDouble(0.0)
	xPtr = xParam.asFloatPtr()
	yParam = OpenMaya.MScriptUtil()
	yParam.createFromDouble(0.0)
	yPtr = yParam.asFloatPtr()
	zParam = OpenMaya.MScriptUtil()
	zParam.createFromDouble(0.0)
	zPtr = zParam.asFloatPtr()
	numDataFn.getData3Float(xPtr, yPtr, zPtr)
	return OpenMaya.MFloatVector(
		OpenMaya.MScriptUtil(xPtr).asFloat(),
		OpenMaya.MScriptUtil(yPtr).asFloat(),
		OpenMaya.MScriptUtil(zPtr).asFloat()
	)

def __hasTweaks( meshDagPath ):

	fnDN = OpenMaya.MFnDependencyNode( meshDagPath.node() )

	# Tweaks exist only if the multi "pnts" attribute contains plugs
	# which contain non-zero tweak values.
	tweakPlug = fnDN.findPlug("pnts")
	if not tweakPlug.isNull():

		if not tweakPlug.isArray():
			raise RuntimeError( "tweakPlug is not an array plug" )

		numElements = tweakPlug.numElements()
		for i in range(numElements):
			tweak = tweakPlug.elementByPhysicalIndex(i)
			if not tweak.isNull():
				tweakData = __getFloat3PlugValue(tweak)
				if 0 != tweakData.x or 0 != tweakData.y or 0 != tweakData.z:
					return True

	return False

def __hasHistory( meshDagPath ):

	fnDN = OpenMaya.MFnDependencyNode( meshDagPath.node() )

	return fnDN.findPlug("inMesh").isConnected()

def __processUpstreamNode(data, meshDagPath, dgModifier):

	if __hasHistory( meshDagPath ):
		# Just swap the connections around
		tempPlugArray = OpenMaya.MPlugArray()
		data.meshNodeDestPlug.connectedTo(tempPlugArray, True, False)
		assert( tempPlugArray.length() == 1 )

		data.upstreamNodeSrcPlug = tempPlugArray[0]

		data.upstreamNodeShape = data.upstreamNodeSrcPlug.node()

		data.upstreamNodeSrcAttr = data.upstreamNodeSrcPlug.attribute()

		dgModifier.disconnect(data.upstreamNodeSrcPlug, data.meshNodeDestPlug)
		dgModifier.doIt()

	else:
		# Duplicate mesh, mark as "intermediate", and reconnect in the DAG
		dagNodeFn = OpenMaya.MFnDagNode( data.meshNodeShape )

		data.upstreamNodeTransform = dagNodeFn.duplicate(False, False)
		dagNodeFn.setObject(data.upstreamNodeTransform)

		fDagModifier = OpenMaya.MDagModifier()

		if dagNodeFn.childCount() < 1:
			raise RuntimeError( "Duplicated mesh has no shape" )

		data.upstreamNodeShape = dagNodeFn.child(0)

		fDagModifier.reparentNode(data.upstreamNodeShape, data.meshNodeTransform)
		fDagModifier.doIt()

		dagNodeFn.setObject(data.upstreamNodeShape)
		dagNodeFn.setIntermediateObject(True)

		data.upstreamNodeSrcAttr = dagNodeFn.attribute("outMesh")
		data.upstreamNodeSrcPlug = dagNodeFn.findPlug("outMesh")

		fDagModifier.deleteNode(data.upstreamNodeTransform)
		fDagModifier.doIt()

def __processTweaks(data, dgModifier, modifierNode):

	tweakIndexArray = OpenMaya.MIntArray()

	fnDN = OpenMaya.MFnDependencyNode()

	tweakDataArray = OpenMaya.MObjectArray()
	tweakSrcConnectionCountArray = OpenMaya.MIntArray()
	tweakSrcConnectionPlugArray = OpenMaya.MPlugArray()
	tweakDstConnectionCountArray = OpenMaya.MIntArray()
	tweakDstConnectionPlugArray = OpenMaya.MPlugArray()
	tempPlugArray = OpenMaya.MPlugArray()

	tweakNode = dgModifier.createNode("polyTweak")
	fnDN.setObject(tweakNode)
	tweakNodeSrcAttr = fnDN.attribute("output")
	tweakNodeDestAttr = fnDN.attribute("inputPolymesh")
	tweakNodeTweakAttr = fnDN.attribute("tweak")

	fnDN.setObject(data.meshNodeShape)
	meshTweakPlug = fnDN.findPlug("pnts")

	if not meshTweakPlug.isArray() :
		raise RuntimeError( "meshTweakPlug is not an array plug" )

	numElements = meshTweakPlug.numElements()
	for i in range(numElements):
		tweak = meshTweakPlug.elementByPhysicalIndex(i)

		if not tweak.isNull():

			tweakIndexArray.append( tweak.logicalIndex() )

			tweakData = tweak.asMObject()
			tweakDataArray.append(tweakData)

			if not tweak.isCompound():
				raise RuntimeError( "Element tweak plug is not a compound" )

			numChildren = tweak.numChildren()
			for j in range(numChildren):
				tweakChild = tweak.child(j)
				if tweakChild.isConnected():

					tempPlugArray.clear()
					if tweakChild.connectedTo(tempPlugArray, False, True):
						numSrcConnections = tempPlugArray.length()
						tweakSrcConnectionCountArray.append(numSrcConnections)

						for k in range(numSrcConnections):
							tweakSrcConnectionPlugArray.append(tempPlugArray[k])
							dgModifier.disconnect(tweakChild, tempPlugArray[k])
					else:
						tweakSrcConnectionCountArray.append(0)

					tempPlugArray.clear()
					if tweakChild.connectedTo(tempPlugArray, True, False):
						assert( tempPlugArray.length() == 1 )

						tweakDstConnectionCountArray.append(1)
						tweakDstConnectionPlugArray.append(tempPlugArray[0])
						dgModifier.disconnect(tempPlugArray[0], tweakChild)
					else:
						tweakDstConnectionCountArray.append(0)
				else:
					tweakSrcConnectionCountArray.append(0)
					tweakDstConnectionCountArray.append(0)

	polyTweakPlug = OpenMaya.MPlug(tweakNode, tweakNodeTweakAttr)
	numTweaks = tweakIndexArray.length()
	srcOffset = 0
	dstOffset = 0
	for i in range(numTweaks):

		tweak = polyTweakPlug.elementByLogicalIndex(tweakIndexArray[i])
		tweak.setMObject(tweakDataArray[i])

		if not tweak.isCompound():
			raise RuntimeError( "Element plug 'tweak' is not a compound" )

		numChildren = tweak.numChildren()
		for j in range(numChildren):
			tweakChild = tweak.child(j)

			if 0 < tweakSrcConnectionCountArray[i*numChildren + j]:
				k = 0
				while (k < tweakSrcConnectionCountArray[i*numChildren + j]):
					dgModifier.connect(tweakChild, tweakSrcConnectionPlugArray[srcOffset])
					srcOffset += 1
					k += 1

			if 0 < tweakDstConnectionCountArray[i*numChildren + j]:
				dgModifier.connect(tweakDstConnectionPlugArray[dstOffset], tweakChild)
				dstOffset += 1

	tweakDestPlug = OpenMaya.MPlug( tweakNode, tweakNodeDestAttr )
	dgModifier.connect( data.upstreamNodeSrcPlug, tweakDestPlug )

	tweakSrcPlug = OpenMaya.MPlug( tweakNode, tweakNodeSrcAttr)
	modifierDestPlug = OpenMaya.MPlug( modifierNode, data.modifierNodeDestAttr )
	dgModifier.connect( tweakSrcPlug, modifierDestPlug )

def __connectNodes( modifierNode, meshDagPath ):
	class MeshOpHolderData:
		def __init__(self):
			self.meshNodeTransform = OpenMaya.MObject()
			self.meshNodeShape = OpenMaya.MObject()
			self.meshNodeDestPlug = OpenMaya.MPlug()
			self.meshNodeDestAttr = OpenMaya.MObject()

			self.upstreamNodeTransform = OpenMaya.MObject()
			self.upstreamNodeShape = OpenMaya.MObject()
			self.upstreamNodeSrcPlug = OpenMaya.MPlug()
			self.upstreamNodeSrcAttr = OpenMaya.MObject()

			self.modifierNodeSrcAttr = OpenMaya.MObject()
			self.modifierNodeDestAttr = OpenMaya.MObject()

	data = MeshOpHolderData()

	fnDN = OpenMaya.MFnDependencyNode( modifierNode )
	data.modifierNodeSrcAttr = fnDN.attribute("result")
	data.modifierNodeDestAttr = fnDN.attribute("parm_input")

	data.meshNodeShape = meshDagPath.node()
	dagNodeFn = OpenMaya.MFnDagNode( data.meshNodeShape )

	if dagNodeFn.parentCount() == 0:
		raise RuntimeError( "Mesh shape has no parent transform" )

	data.meshNodeTransform = dagNodeFn.parent(0)
	data.meshNodeDestPlug = dagNodeFn.findPlug("inMesh")
	data.meshNodeDestAttr = data.meshNodeDestPlug.attribute()

	dgModifier = OpenMaya.MDGModifier()
	__processUpstreamNode(data, meshDagPath, dgModifier)

	if __hasTweaks( meshDagPath ):
		__processTweaks(data, dgModifier, modifierNode)
	else:
		modifierDestPlug = OpenMaya.MPlug(modifierNode, data.modifierNodeDestAttr)
		dgModifier.connect(data.upstreamNodeSrcPlug, modifierDestPlug)

	modifierSrcPlug = OpenMaya.MPlug(modifierNode, data.modifierNodeSrcAttr)
	meshDestAttr = OpenMaya.MPlug(data.meshNodeShape, data.meshNodeDestAttr)

	dgModifier.connect(modifierSrcPlug, meshDestAttr)

	dgModifier.doIt()

def __setParameters( op, kw ):

	for paramName, paramValue in kw.items():
		op.parameters().setValidatedParameterValue( paramName, paramValue )

def __createMeshOpNode( className, classVersion, **kw ):

	shortClassName = className.split( '/' ).pop()

	modifierNodeName = cmds.createNode( "ieOpHolderNode", name = shortClassName + "#" )

	ph = IECoreMaya.ParameterisedHolder( str(modifierNodeName) )
	op = ph.setParameterised( className, classVersion, "IECORE_OP_PATHS" )

	__setParameters( op, kw )

	selList = OpenMaya.MSelectionList()
	selList.add( modifierNodeName )
	modifierNode = OpenMaya.MObject()
	s = selList.getDependNode( 0, modifierNode )

	return modifierNode

def __applyMeshOp( meshNode, className, classVersion, kw ):

	op = IECore.ClassLoader.defaultOpLoader().load( className, classVersion )

	__setParameters( op, **kw )

	# \todo Apply op and convert result back into original object

def create( meshDagPath, className, classVersion, **kw):

	if type(meshDagPath) is str:
		sel = OpenMaya.MSelectionList()
		sel.add( meshDagPath )
		meshDagPath = OpenMaya.MDagPath()
		sel.getDagPath( 0,  meshDagPath)
		meshDagPath.extendToShape()

	constructionHistoryEnabled = IECoreMaya.mel("constructionHistory -q -tgl").value

	if not __hasHistory( meshDagPath ) and constructionHistoryEnabled == 0:

		# \todo we can't actually do this right now because we're unable to convert the resultant MeshPrimitive
		# back into the original meshNode MObject given to us
		raise RuntimeError( "Currently unable to apply MeshOp in-place " )

		meshNode = meshDagPath.node()

		__applyMeshOp(meshNode, className, classVersion, **kw )

		return None
	else:
		modifierNode = __createMeshOpNode( className, classVersion, **kw )

		__connectNodes( modifierNode, meshDagPath )

		fnDN = OpenMaya.MFnDependencyNode( modifierNode )

		return str( fnDN.name() )

def createUI( className, classVersion, **kw ):

	# \todo Should we use list selection instead?
	selectedMeshes = cmds.filterExpand( sm = 12 )

	if not selectedMeshes:
		raise RuntimeError( "No mesh selected" )

	modifierNodes = []

	for mesh in selectedMeshes:

		sel = OpenMaya.MSelectionList()
		sel.add( mesh )
		meshDagPath = OpenMaya.MDagPath()
		sel.getDagPath( 0,  meshDagPath)
		meshDagPath.extendToShape()

		modifierNode = create( meshDagPath, className, classVersion, **kw )

		if modifierNode :

			modifierNodes += [ modifierNode ]

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

import maya.OpenMaya as OpenMaya
import maya.cmds as cmds

import IECoreMaya
import IECore

def __getFloat3PlugValue(plug):

	# Retrieve the value as an MObject
	object = plug.asMObject()

	# Convert the MObject to a float3
	numDataFn = OpenMaya.MFnNumericData(object)
	xParam = OpenMaya.MScriptUtil()
	xParam.createFromDouble(0.0)
	xPtr = xParam.asFloatPtr()
	yParam = OpenMaya.MScriptUtil()
	yParam.createFromDouble(0.0)
	yPtr = yParam.asFloatPtr()
	zParam = OpenMaya.MScriptUtil()
	zParam.createFromDouble(0.0)
	zPtr = zParam.asFloatPtr()
	numDataFn.getData3Float(xPtr, yPtr, zPtr)
	return OpenMaya.MFloatVector(
		OpenMaya.MScriptUtil(xPtr).asFloat(),
		OpenMaya.MScriptUtil(yPtr).asFloat(),
		OpenMaya.MScriptUtil(zPtr).asFloat()
	)

def __hasTweaks( meshDagPath ):

	fnDN = OpenMaya.MFnDependencyNode( meshDagPath.node() )

	# Tweaks exist only if the multi "pnts" attribute contains plugs
	# which contain non-zero tweak values.
	tweakPlug = fnDN.findPlug("pnts")
	if not tweakPlug.isNull():

		if not tweakPlug.isArray():
			raise RuntimeError( "tweakPlug is not an array plug" )

		numElements = tweakPlug.numElements()
		for i in range(numElements):
			tweak = tweakPlug.elementByPhysicalIndex(i)
			if not tweak.isNull():
				tweakData = __getFloat3PlugValue(tweak)
				if 0 != tweakData.x or 0 != tweakData.y or 0 != tweakData.z:
					return True

	return False

def __hasHistory( meshDagPath ):

	fnDN = OpenMaya.MFnDependencyNode( meshDagPath.node() )

	return fnDN.findPlug("inMesh").isConnected()

def __processUpstreamNode(data, meshDagPath, dgModifier):

	if __hasHistory( meshDagPath ):
		# Just swap the connections around
		tempPlugArray = OpenMaya.MPlugArray()
		data.meshNodeDestPlug.connectedTo(tempPlugArray, True, False)
		assert( tempPlugArray.length() == 1 )

		data.upstreamNodeSrcPlug = tempPlugArray[0]

		data.upstreamNodeShape = data.upstreamNodeSrcPlug.node()

		data.upstreamNodeSrcAttr = data.upstreamNodeSrcPlug.attribute()

		dgModifier.disconnect(data.upstreamNodeSrcPlug, data.meshNodeDestPlug)
		dgModifier.doIt()

	else:
		# Duplicate mesh, mark as "intermediate", and reconnect in the DAG
		dagNodeFn = OpenMaya.MFnDagNode( data.meshNodeShape )

		data.upstreamNodeTransform = dagNodeFn.duplicate(False, False)
		dagNodeFn.setObject(data.upstreamNodeTransform)

		fDagModifier = OpenMaya.MDagModifier()

		if dagNodeFn.childCount() < 1:
			raise RuntimeError( "Duplicated mesh has no shape" )

		data.upstreamNodeShape = dagNodeFn.child(0)

		fDagModifier.reparentNode(data.upstreamNodeShape, data.meshNodeTransform)
		fDagModifier.doIt()

		dagNodeFn.setObject(data.upstreamNodeShape)
		dagNodeFn.setIntermediateObject(True)

		data.upstreamNodeSrcAttr = dagNodeFn.attribute("outMesh")
		data.upstreamNodeSrcPlug = dagNodeFn.findPlug("outMesh")

		fDagModifier.deleteNode(data.upstreamNodeTransform)
		fDagModifier.doIt()

def __processTweaks(data, dgModifier, modifierNode):

	tweakIndexArray = OpenMaya.MIntArray()

	fnDN = OpenMaya.MFnDependencyNode()

	tweakDataArray = OpenMaya.MObjectArray()
	tweakSrcConnectionCountArray = OpenMaya.MIntArray()
	tweakSrcConnectionPlugArray = OpenMaya.MPlugArray()
	tweakDstConnectionCountArray = OpenMaya.MIntArray()
	tweakDstConnectionPlugArray = OpenMaya.MPlugArray()
	tempPlugArray = OpenMaya.MPlugArray()

	tweakNode = dgModifier.createNode("polyTweak")
	fnDN.setObject(tweakNode)
	tweakNodeSrcAttr = fnDN.attribute("output")
	tweakNodeDestAttr = fnDN.attribute("inputPolymesh")
	tweakNodeTweakAttr = fnDN.attribute("tweak")

	fnDN.setObject(data.meshNodeShape)
	meshTweakPlug = fnDN.findPlug("pnts")

	if not meshTweakPlug.isArray() :
		raise RuntimeError( "meshTweakPlug is not an array plug" )

	numElements = meshTweakPlug.numElements()
	for i in range(numElements):
		tweak = meshTweakPlug.elementByPhysicalIndex(i)

		if not tweak.isNull():

			tweakIndexArray.append( tweak.logicalIndex() )

			tweakData = tweak.asMObject()
			tweakDataArray.append(tweakData)

			if not tweak.isCompound():
				raise RuntimeError( "Element tweak plug is not a compound" )

			numChildren = tweak.numChildren()
			for j in range(numChildren):
				tweakChild = tweak.child(j)
				if tweakChild.isConnected():

					tempPlugArray.clear()
					if tweakChild.connectedTo(tempPlugArray, False, True):
						numSrcConnections = tempPlugArray.length()
						tweakSrcConnectionCountArray.append(numSrcConnections)

						for k in range(numSrcConnections):
							tweakSrcConnectionPlugArray.append(tempPlugArray[k])
							dgModifier.disconnect(tweakChild, tempPlugArray[k])
					else:
						tweakSrcConnectionCountArray.append(0)

					tempPlugArray.clear()
					if tweakChild.connectedTo(tempPlugArray, True, False):
						assert( tempPlugArray.length() == 1 )

						tweakDstConnectionCountArray.append(1)
						tweakDstConnectionPlugArray.append(tempPlugArray[0])
						dgModifier.disconnect(tempPlugArray[0], tweakChild)
					else:
						tweakDstConnectionCountArray.append(0)
				else:
					tweakSrcConnectionCountArray.append(0)
					tweakDstConnectionCountArray.append(0)

	polyTweakPlug = OpenMaya.MPlug(tweakNode, tweakNodeTweakAttr)
	numTweaks = tweakIndexArray.length()
	srcOffset = 0
	dstOffset = 0
	for i in range(numTweaks):

		tweak = polyTweakPlug.elementByLogicalIndex(tweakIndexArray[i])
		tweak.setMObject(tweakDataArray[i])

		if not tweak.isCompound():
			raise RuntimeError( "Element plug 'tweak' is not a compound" )

		numChildren = tweak.numChildren()
		for j in range(numChildren):
			tweakChild = tweak.child(j)

			if 0 < tweakSrcConnectionCountArray[i*numChildren + j]:
				k = 0
				while (k < tweakSrcConnectionCountArray[i*numChildren + j]):
					dgModifier.connect(tweakChild, tweakSrcConnectionPlugArray[srcOffset])
					srcOffset += 1
					k += 1

			if 0 < tweakDstConnectionCountArray[i*numChildren + j]:
				dgModifier.connect(tweakDstConnectionPlugArray[dstOffset], tweakChild)
				dstOffset += 1

	tweakDestPlug = OpenMaya.MPlug( tweakNode, tweakNodeDestAttr )
	dgModifier.connect( data.upstreamNodeSrcPlug, tweakDestPlug )

	tweakSrcPlug = OpenMaya.MPlug( tweakNode, tweakNodeSrcAttr)
	modifierDestPlug = OpenMaya.MPlug( modifierNode, data.modifierNodeDestAttr )
	dgModifier.connect( tweakSrcPlug, modifierDestPlug )

def __connectNodes( modifierNode, meshDagPath ):
	class MeshOpHolderData:
		def __init__(self):
			self.meshNodeTransform = OpenMaya.MObject()
			self.meshNodeShape = OpenMaya.MObject()
			self.meshNodeDestPlug = OpenMaya.MPlug()
			self.meshNodeDestAttr = OpenMaya.MObject()

			self.upstreamNodeTransform = OpenMaya.MObject()
			self.upstreamNodeShape = OpenMaya.MObject()
			self.upstreamNodeSrcPlug = OpenMaya.MPlug()
			self.upstreamNodeSrcAttr = OpenMaya.MObject()

			self.modifierNodeSrcAttr = OpenMaya.MObject()
			self.modifierNodeDestAttr = OpenMaya.MObject()

	data = MeshOpHolderData()

	fnDN = OpenMaya.MFnDependencyNode( modifierNode )
	data.modifierNodeSrcAttr = fnDN.attribute("result")
	data.modifierNodeDestAttr = fnDN.attribute("parm_input")

	data.meshNodeShape = meshDagPath.node()
	dagNodeFn = OpenMaya.MFnDagNode( data.meshNodeShape )

	if dagNodeFn.parentCount() == 0:
		raise RuntimeError( "Mesh shape has no parent transform" )

	data.meshNodeTransform = dagNodeFn.parent(0)
	data.meshNodeDestPlug = dagNodeFn.findPlug("inMesh")
	data.meshNodeDestAttr = data.meshNodeDestPlug.attribute()

	dgModifier = OpenMaya.MDGModifier()
	__processUpstreamNode(data, meshDagPath, dgModifier)

	if __hasTweaks( meshDagPath ):
		__processTweaks(data, dgModifier, modifierNode)
	else:
		modifierDestPlug = OpenMaya.MPlug(modifierNode, data.modifierNodeDestAttr)
		dgModifier.connect(data.upstreamNodeSrcPlug, modifierDestPlug)

	modifierSrcPlug = OpenMaya.MPlug(modifierNode, data.modifierNodeSrcAttr)
	meshDestAttr = OpenMaya.MPlug(data.meshNodeShape, data.meshNodeDestAttr)

	dgModifier.connect(modifierSrcPlug, meshDestAttr)

	dgModifier.doIt()

def __setParameters( op, kw ):

	for paramName, paramValue in kw.items():
		op.parameters().setValidatedParameterValue( paramName, paramValue )

def __createMeshOpNode( className, classVersion, **kw ):

	shortClassName = className.split( '/' ).pop()

	modifierNodeName = cmds.createNode( "ieOpHolderNode", name = shortClassName + "#" )

	ph = IECoreMaya.ParameterisedHolder( str(modifierNodeName) )
	op = ph.setParameterised( className, classVersion, "IECORE_OP_PATHS" )

	__setParameters( op, kw )

	selList = OpenMaya.MSelectionList()
	selList.add( modifierNodeName )
	modifierNode = OpenMaya.MObject()
	s = selList.getDependNode( 0, modifierNode )

	return modifierNode

def __applyMeshOp( meshNode, className, classVersion, kw ):

	op = IECore.ClassLoader.defaultOpLoader().load( className, classVersion )

	__setParameters( op, **kw )

	# \todo Apply op and convert result back into original object

def create( meshDagPath, className, classVersion, **kw):

	if type(meshDagPath) is str:
		sel = OpenMaya.MSelectionList()
		sel.add( meshDagPath )
		meshDagPath = OpenMaya.MDagPath()
		sel.getDagPath( 0,  meshDagPath)
		meshDagPath.extendToShape()

	constructionHistoryEnabled = IECoreMaya.mel("constructionHistory -q -tgl").value

	if not __hasHistory( meshDagPath ) and constructionHistoryEnabled == 0:

		# \todo we can't actually do this right now because we're unable to convert the resultant MeshPrimitive
		# back into the original meshNode MObject given to us
		raise RuntimeError( "Currently unable to apply MeshOp in-place " )

		meshNode = meshDagPath.node()

		__applyMeshOp(meshNode, className, classVersion, **kw )

		return None
	else:
		modifierNode = __createMeshOpNode( className, classVersion, **kw )

		__connectNodes( modifierNode, meshDagPath )

		fnDN = OpenMaya.MFnDependencyNode( modifierNode )

		return str( fnDN.name() )

def createUI( className, classVersion, **kw ):

	selectedTransforms = cmds.ls( selection = True, type = "transform" ) or []
	selectedTransformMeshShapes = cmds.listRelatives( selectedTransforms, type = "mesh" ) or []

	selectedMeshes = cmds.ls( selection = True, type = "mesh" ) or []
	selectedMeshes += selectedTransformMeshShapes

	if not selectedMeshes:
		raise RuntimeError( "No mesh selected" )

	modifierNodes = []

	for mesh in selectedMeshes:

		sel = OpenMaya.MSelectionList()
		sel.add( mesh )
		meshDagPath = OpenMaya.MDagPath()
		sel.getDagPath( 0,  meshDagPath)
		meshDagPath.extendToShape()

		modifierNode = create( meshDagPath, className, classVersion, **kw )

		if modifierNode :

			modifierNodes += [ modifierNode ]

	return modifierNodes
<|endoftext|>


<commit_before>import logging
import xml.etree.ElementTree as ET
from django.core.management.base import BaseCommand

from ...models import Transcript, TranscriptMetadata, Topic, Source

logger = logging.getLogger('django')
aapb_url_prefix = 'http://americanarchive.org/api/'

class Command(BaseCommand):
    help = 'Gets the AAPB PBCore information for a given transcript'

    def _topics(self, transcript, root):
        topics = []
        # science, politics/public affairs, etc. List to come from Sadie and/or
        # Casey
        for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreGenre'):
            if child.attrib['annotation'] == 'topic':
                topics.append(child.text)
                for topic in set(topics):
                    topic_object, _ = Topic.objects.get_or_create(topic=topic)
                    topic_object.transcripts.add(transcript)

    def _sources(self, transcript, root):
        source_candidates = []
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreAnnotation'):
                if child.attrib['annotationType'] == 'organization':
                    logger.info('Found source {} for transcript: {}'.format(
                        child.text, transcript
                    ))
                    source_candidates.append(child.text)
        except:
            pass
        for candidate in set(source_candidates):
            source = Source.objects.get(pbcore_source=candidate)
            source.transcripts.add(transcript)

    def _description(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreDescription'):
                if child.attrib['descriptionType'] == 'Description':
                    return child.text
        except:
            return ''

    def _series_title(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreTitle'):
                if child.attrib['titleType'] == 'Series' or child.attrib['titleType'] == 'Program':
                    return child.text
        except:
            return ''

    def _broadcast_date(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreAssetDate'):
                return child.text
        except:
            return ''

    def handle(self, *args, **options):
        for transcript in Transcript.objects.all():
            try:
                tree = ET.ElementTree(ET.fromstringlist(transcript.aapb_xml))
                root = tree.getroot()
                self._topics(transcript, root)
                self._sources(transcript, root)
                metadata = {
                    'description': self._description(root),
                    'series': self._series_title(root),
                    'broadcast_date': self._broadcast_date(root),
                }
                tmd, created = TranscriptMetadata.objects.update_or_create(
                    transcript=transcript,
                    defaults=metadata,
                )
                tmd.save()
            except:
                pass
<commit_msg>remove unused variable<commit_after>import logging
import xml.etree.ElementTree as ET
from django.core.management.base import BaseCommand

from ...models import Transcript, TranscriptMetadata, Topic, Source

logger = logging.getLogger('django')

class Command(BaseCommand):
    help = 'Gets the AAPB PBCore information for a given transcript'

    def _topics(self, transcript, root):
        topics = []
        # science, politics/public affairs, etc. List to come from Sadie and/or
        # Casey
        for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreGenre'):
            if child.attrib['annotation'] == 'topic':
                topics.append(child.text)
                for topic in set(topics):
                    topic_object, _ = Topic.objects.get_or_create(topic=topic)
                    topic_object.transcripts.add(transcript)

    def _sources(self, transcript, root):
        source_candidates = []
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreAnnotation'):
                if child.attrib['annotationType'] == 'organization':
                    logger.info('Found source {} for transcript: {}'.format(
                        child.text, transcript
                    ))
                    source_candidates.append(child.text)
        except:
            pass
        for candidate in set(source_candidates):
            source = Source.objects.get(pbcore_source=candidate)
            source.transcripts.add(transcript)

    def _description(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreDescription'):
                if child.attrib['descriptionType'] == 'Description':
                    return child.text
        except:
            return ''

    def _series_title(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreTitle'):
                if child.attrib['titleType'] == 'Series' or child.attrib['titleType'] == 'Program':
                    return child.text
        except:
            return ''

    def _broadcast_date(self, root):
        try:
            for child in root.iter('{http://www.pbcore.org/PBCore/PBCoreNamespace.html}pbcoreAssetDate'):
                return child.text
        except:
            return ''

    def handle(self, *args, **options):
        for transcript in Transcript.objects.all():
            try:
                tree = ET.ElementTree(ET.fromstringlist(transcript.aapb_xml))
                root = tree.getroot()
                self._topics(transcript, root)
                self._sources(transcript, root)
                metadata = {
                    'description': self._description(root),
                    'series': self._series_title(root),
                    'broadcast_date': self._broadcast_date(root),
                }
                tmd, created = TranscriptMetadata.objects.update_or_create(
                    transcript=transcript,
                    defaults=metadata,
                )
                tmd.save()
            except:
                pass
<|endoftext|>


<commit_before>from __future__ import print_function
import os, sys, base64
import MySQLdb, argparse
import time, subprocess
from operator import itemgetter
from datetime import datetime, timedelta
try:
  import configparser
except:
  import ConfigParser as configparser

dirNm, execName = os.path.split(os.path.realpath(sys.argv[0]))
sys.path.insert(1,os.path.realpath(os.path.join(dirNm, "../libexec")))
sys.path.insert(1,os.path.realpath(os.path.join(dirNm, "../site")))

class CmdLineOptions(object):
  """ Command line Options class """

  def __init__(self):
    """ Empty Ctor """
    pass

  def execute(self):
    """ Specify command line arguments and parse the command line"""
    parser = argparse.ArgumentParser()
    parser.add_argument("--confFn",    dest='confFn',    action="store",       default = "xalt_db.conf", help="db name")
    parser.add_argument("--start",     dest='startD',    action="store",       default = None,           help="start date")
    parser.add_argument("--end",       dest='endD',      action="store",       default = None,           help="end date")
    parser.add_argument("--syshost",   dest='syshost',   action="store",       default = "%",            help="syshost")
    parser.add_argument("--clear_bit", dest='clear_bit', action="store_true",  default = False,          help="Clear bit")
    args = parser.parse_args()
    return args

def find_run_files(cursor, args, startdate, enddate):
  query = """
  SELECT exec_path FROM xalt_link
  WHERE uuid is not null
  AND  num_nodes > 1
  AND date >= %s AND date < %s
  """
  cursor.execute(query, (startdate, enddate))
  a = cursor.fetchall()
  resultT = {}
  for entry in a:
    file = entry[0]
    if (os.path.isfile(file)):
      result = capture("execstack " + file)
      if (result[0:1] == 'X'):
        resultT[file] = True

  return resultT

def capture(cmd):
  """
  Capture standard out for a command.
  @param cmd: Command string or array.
  """

  if (type(cmd) == type(' ')):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT, shell =True)
  else:
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)

  return p.communicate()[0]

def clear_stack_bit(file):
  result = capture("execstack " + file)
  if (result[0:1] == 'X'):
    os.system("execstack -c " + file)
    print("clearing stack bit on: ",file)

def main():
  XALT_ETC_DIR = os.environ.get("XALT_ETC_DIR","./")
  args         = CmdLineOptions().execute()
  config       = configparser.ConfigParser()
  configFn     = os.path.join(XALT_ETC_DIR,args.confFn)
  config.read(configFn)

  conn = MySQLdb.connect              \
         (config.get("MYSQL","HOST"), \
          config.get("MYSQL","USER"), \
          base64.b64decode(config.get("MYSQL","PASSWD")), \
          config.get("MYSQL","DB"))
  cursor = conn.cursor()

  enddate = time.strftime('%Y-%m-%d')
  if (args.endD is not None):
    enddate = args.endD

  startdate = (datetime.strptime(enddate, "%Y-%m-%d") - timedelta(90)).strftime('%Y-%m-%d');
  if (args.startD is not None):
    startdate = args.startD

  resultT = find_link_files(cursor, args, startdate, enddate)

  for file in resultT:
    if (args.clear_bit):
      clear_stack_bit(file)
    else:
      print(file)

if ( __name__ == '__main__'): main()
<commit_msg>updated xalt_db_clear_bit_run file<commit_after>from __future__ import print_function
import os, sys, base64
import MySQLdb, argparse
import time, subprocess
from operator import itemgetter
from datetime import datetime, timedelta
try:
  import configparser
except:
  import ConfigParser as configparser

dirNm, execName = os.path.split(os.path.realpath(sys.argv[0]))
sys.path.insert(1,os.path.realpath(os.path.join(dirNm, "../libexec")))
sys.path.insert(1,os.path.realpath(os.path.join(dirNm, "../site")))

class CmdLineOptions(object):
  """ Command line Options class """

  def __init__(self):
    """ Empty Ctor """
    pass

  def execute(self):
    """ Specify command line arguments and parse the command line"""
    parser = argparse.ArgumentParser()
    parser.add_argument("--confFn",    dest='confFn',    action="store",       default = "xalt_db.conf", help="db name")
    parser.add_argument("--start",     dest='startD',    action="store",       default = None,           help="start date")
    parser.add_argument("--end",       dest='endD',      action="store",       default = None,           help="end date")
    parser.add_argument("--syshost",   dest='syshost',   action="store",       default = "%",            help="syshost")
    parser.add_argument("--clear_bit", dest='clear_bit', action="store_true",  default = False,          help="Clear bit")
    args = parser.parse_args()
    return args

def find_run_files(cursor, args, startdate, enddate):
  query = """
  SELECT exec_path FROM xalt_run
  WHERE uuid is not null
  AND  num_nodes > 1
  AND date >= %s AND date < %s
  """
  cursor.execute(query, (startdate, enddate))
  a = cursor.fetchall()
  resultT = {}
  for entry in a:
    file = entry[0]
    if (os.path.isfile(file)):
      result = capture("execstack " + file)
      if (result[0:1] == 'X'):
        resultT[file] = True

  return resultT

def capture(cmd):
  """
  Capture standard out for a command.
  @param cmd: Command string or array.
  """

  if (type(cmd) == type(' ')):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT, shell =True)
  else:
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)

  return p.communicate()[0]

def clear_stack_bit(file):
  result = capture("execstack " + file)
  if (result[0:1] == 'X'):
    os.system("execstack -c " + file)
    print("clearing stack bit on: ",file)

def main():
  XALT_ETC_DIR = os.environ.get("XALT_ETC_DIR","./")
  args         = CmdLineOptions().execute()
  config       = configparser.ConfigParser()
  configFn     = os.path.join(XALT_ETC_DIR,args.confFn)
  config.read(configFn)

  conn = MySQLdb.connect              \
         (config.get("MYSQL","HOST"), \
          config.get("MYSQL","USER"), \
          base64.b64decode(config.get("MYSQL","PASSWD")), \
          config.get("MYSQL","DB"))
  cursor = conn.cursor()

  enddate = time.strftime('%Y-%m-%d')
  if (args.endD is not None):
    enddate = args.endD

  startdate = (datetime.strptime(enddate, "%Y-%m-%d") - timedelta(90)).strftime('%Y-%m-%d');
  if (args.startD is not None):
    startdate = args.startD

  resultT = find_run_files(cursor, args, startdate, enddate)

  for file in resultT:
    if (args.clear_bit):
      clear_stack_bit(file)
    else:
      print(file)

if ( __name__ == '__main__'): main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# svnmerge-migrate-history.py: Migrate merge history from svnmerge.py's
#                              format to Subversion 1.5's format.
#
# ====================================================================
# Copyright (c) 2007 CollabNet.  All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.  The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
# This software consists of voluntary contributions made by many
# individuals.  For exact contribution history, see the revision
# history and logs, available at http://subversion.tigris.org/.
# ====================================================================

import sys
import os
import sre
import getopt
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt

try:
  import svn.core
  import svn.fs
  import svn.repos
except ImportError, e:
  print >> sys.stderr, \
        "ERROR: Unable to import Subversion's Python bindings: '%s'\n" \
        "Hint: Set your PYTHONPATH environment variable, or adjust your " \
        "PYTHONSTARTUP\nfile to point to your Subversion install " \
        "location's svn-python directory." % e
  sys.exit(1)

# Pretend we have boolean data types for older Python versions.
try:
  True
  False
except:
  True = 1
  False = 0

def usage_and_exit(error_msg=None):
  """Write usage information and exit.  If ERROR_MSG is provide, that
  error message is printed first (to stderr), the usage info goes to
  stderr, and the script exits with a non-zero status.  Otherwise,
  usage info goes to stdout and the script exits with a zero status."""
  progname = os.path.basename(sys.argv[0])

  stream = error_msg and sys.stderr or sys.stdout
  if error_msg:
    print >> stream, "ERROR: %s\n" % error_msg
  print >> stream, """usage: %s REPOS_PATH [PATH_PREFIX...] [--verbose]
       %s --help

Migrate merge history from svnmerge.py's format to Subversion 1.5's
format, stopping as soon as merge history is encountered for a
directory tree.

PATH_PREFIX defines the repository paths to examine for merge history
to migrate.  If none are listed, the repository's root is examined.

Example: %s /path/to/repos trunk branches tags
""" % (progname, progname, progname)
  sys.exit(error_msg and 1 or 0)

class Migrator:
  "Migrates merge history."

  repos_path = None
  path_prefixes = None
  verbose = False
  fs = None

  def run(self):
    self.fs = svn.repos.fs(svn.repos.open(self.repos_path))

    revnum = svn.fs.youngest_rev(self.fs)
    root = svn.fs.revision_root(self.fs, revnum)

    # Validate path prefixes, retaining path calculations performed in
    # the process.
    leading_paths = []
    for path_prefix in self.path_prefixes:
      path = "/".join(path_prefix[:-1])
      leading_paths.append(path)
      if svn.fs.check_path(root, path) != svn.core.svn_node_dir:
        raise Exception("Repository path '%s' is not a directory" % path)

    for i in range(0, len(self.path_prefixes)):
      prefix = self.path_prefixes[i]
      self.process_dir(root, revnum, leading_paths[i],
                       prefix[len(prefix) - 1] + ".*")

  def process_dir(self, root, revnum, dir_path, pattern=None):
    "Recursively process children of DIR_PATH."
    dirents = svn.fs.dir_entries(root, dir_path)
    for name in dirents.keys():
      if not dirents[name].kind == svn.core.svn_node_dir:
        continue
      if pattern is None or sre.match(pattern, name):
        if dir_path == "":
          child_path = name
        else:
          child_path = "%s/%s" % (dir_path, name)
        if self.verbose:
          print "Examining path '%s' for conversion" % child_path
        if not self.convert_path_history(root, revnum, child_path):
          self.process_dir(root, revnum, child_path)

  def convert_path_history(self, root, revnum, path):
    "Migrate the merge history for PATH at ROOT at REVNUM."

    ### Bother to handle any pre-existing, inherited svn:mergeinfo?

    # Retrieve svnmerge.py's merge history meta data, and roll it into
    # Subversion 1.5 mergeinfo.
    mergeinfo_prop_val = svn.fs.node_prop(root, path,
                                          svn.core.SVN_PROP_MERGEINFO)
    integrated_prop_val = svn.fs.node_prop(root, path, "svnmerge-integrated")
    if self.verbose:
      print "Discovered pre-existing Subversion mergeinfo of '%s'" % \
        mergeinfo_prop_val
      print "Discovered svnmerge.py mergeinfo of '%s'" % integrated_prop_val
    mergeinfo_prop_val = self.add_to_mergeinfo(integrated_prop_val,
                                               mergeinfo_prop_val)
    ### LATER: We handle svnmerge-blocked by converting it into
    ### svn:mergeinfo, until revision blocking becomes available in
    ### Subversion's core.
    blocked_prop_val = svn.fs.node_prop(root, path, "svnmerge-blocked")
    if self.verbose:
      print "Discovered svnmerge.py blocked revisions of '%s'" % \
        blocked_prop_val
    mergeinfo_prop_val = self.add_to_mergeinfo(blocked_prop_val,
                                               mergeinfo_prop_val)

    if mergeinfo_prop_val is not None:
      # Begin a transaction in which we'll manipulate merge-related
      # properties.  Open the transaction root.
      txn = svn.fs.begin_txn2(self.fs, revnum, 0)
      root = svn.fs.txn_root(txn)

      # Manipulate the merge history.
      if self.verbose:
        print "Queuing change of %s to '%s'" % \
          (svn.core.SVN_PROP_MERGEINFO, mergeinfo_prop_val)
      svn.fs.change_node_prop(root, path, svn.core.SVN_PROP_MERGEINFO,
                              mergeinfo_prop_val)

      # Remove old property values.
      if integrated_prop_val is not None:
        if self.verbose:
          print "Queuing removal of svnmerge-integrated"
        svn.fs.change_node_prop(root, path, "svnmerge-integrated", None)
      if blocked_prop_val is not None:
        if self.verbose:
          print "Queuing removal of svnmerge-blocked"
        svn.fs.change_node_prop(root, path, "svnmerge-blocked", None)

      # Commit the transaction containing our property manipulation.
      if self.verbose:
        print "Committing the transaction containing the above changes"
      conflict, new_revnum = svn.fs.commit_txn(txn)
      if conflict:
        ### TODO: Do something more intelligent with the possible conflict.
        raise Exception("Conflict encountered (%s)" % conflict)
      print "Migrated merge history on '%s' in r%d" % (path, new_revnum)
      return True
    else:
      # No merge history to manipulate.
      if self.verbose:
        print "No merge history on '%s'" % path
      return False

  def add_to_mergeinfo(self, svnmerge_prop_val, mergeinfo_prop_val):
    if svnmerge_prop_val is not None:
      if mergeinfo_prop_val:
        mergeinfo = svn.core.svn_mergeinfo_parse(mergeinfo_prop_val)
        to_migrate = svn.core.svn_mergeinfo_parse(svnmerge_prop_val)
        mergeinfo = svn.core.svn_mergeinfo_merge(mergeinfo, to_migrate)
        mergeinfo_prop_val = svn.core.svn_mergeinfo_to_stringbuf(mergeinfo)
      else:
        mergeinfo_prop_val = svnmerge_prop_val

    return mergeinfo_prop_val

  def set_path_prefixes(self, prefixes):
    "Decompose path prefixes into something meaningful for comparision."
    self.path_prefixes = []
    for prefix in prefixes:
      prefix_components = []
      parts = prefix.split("/")
      for i in range(0, len(parts)):
        prefix_components.append(parts[i])
      self.path_prefixes.append(prefix_components)

def main():
  try:
    opts, args = my_getopt(sys.argv[1:], "vh?",
                           ["from-paths=", "verbose", "help"])
  except:
    usage_and_exit("Unable to process arguments/options")

  migrator = Migrator()

  # Process arguments.
  if len(args) >= 1:
    migrator.repos_path = svn.core.svn_path_canonicalize(args[0])
    if len(args) >= 2:
      path_prefixes = args[1:]
    else:
      # Default to the root of the repository.
      path_prefixes = [ "" ]
  else:
    usage_and_exit("REPOS_PATH argument required")

  # Process options.
  for opt, value in opts:
    if opt == "--help" or opt in ("-h", "-?"):
      usage_and_exit()
    elif opt == "--verbose" or opt == "-v":
      migrator.verbose = True
    else:
      usage_and_exit("Unknown option '%s'" % opt)

  migrator.set_path_prefixes(path_prefixes)
  migrator.run()

if __name__ == "__main__":
  main()
<commit_msg>Update a use of the API.<commit_after>#!/usr/bin/env python
#
# svnmerge-migrate-history.py: Migrate merge history from svnmerge.py's
#                              format to Subversion 1.5's format.
#
# ====================================================================
# Copyright (c) 2007 CollabNet.  All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.  The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
# This software consists of voluntary contributions made by many
# individuals.  For exact contribution history, see the revision
# history and logs, available at http://subversion.tigris.org/.
# ====================================================================

import sys
import os
import sre
import getopt
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt

try:
  import svn.core
  import svn.fs
  import svn.repos
except ImportError, e:
  print >> sys.stderr, \
        "ERROR: Unable to import Subversion's Python bindings: '%s'\n" \
        "Hint: Set your PYTHONPATH environment variable, or adjust your " \
        "PYTHONSTARTUP\nfile to point to your Subversion install " \
        "location's svn-python directory." % e
  sys.exit(1)

# Pretend we have boolean data types for older Python versions.
try:
  True
  False
except:
  True = 1
  False = 0

def usage_and_exit(error_msg=None):
  """Write usage information and exit.  If ERROR_MSG is provide, that
  error message is printed first (to stderr), the usage info goes to
  stderr, and the script exits with a non-zero status.  Otherwise,
  usage info goes to stdout and the script exits with a zero status."""
  progname = os.path.basename(sys.argv[0])

  stream = error_msg and sys.stderr or sys.stdout
  if error_msg:
    print >> stream, "ERROR: %s\n" % error_msg
  print >> stream, """usage: %s REPOS_PATH [PATH_PREFIX...] [--verbose]
       %s --help

Migrate merge history from svnmerge.py's format to Subversion 1.5's
format, stopping as soon as merge history is encountered for a
directory tree.

PATH_PREFIX defines the repository paths to examine for merge history
to migrate.  If none are listed, the repository's root is examined.

Example: %s /path/to/repos trunk branches tags
""" % (progname, progname, progname)
  sys.exit(error_msg and 1 or 0)

class Migrator:
  "Migrates merge history."

  repos_path = None
  path_prefixes = None
  verbose = False
  fs = None

  def run(self):
    self.fs = svn.repos.fs(svn.repos.open(self.repos_path))

    revnum = svn.fs.youngest_rev(self.fs)
    root = svn.fs.revision_root(self.fs, revnum)

    # Validate path prefixes, retaining path calculations performed in
    # the process.
    leading_paths = []
    for path_prefix in self.path_prefixes:
      path = "/".join(path_prefix[:-1])
      leading_paths.append(path)
      if svn.fs.check_path(root, path) != svn.core.svn_node_dir:
        raise Exception("Repository path '%s' is not a directory" % path)

    for i in range(0, len(self.path_prefixes)):
      prefix = self.path_prefixes[i]
      self.process_dir(root, revnum, leading_paths[i],
                       prefix[len(prefix) - 1] + ".*")

  def process_dir(self, root, revnum, dir_path, pattern=None):
    "Recursively process children of DIR_PATH."
    dirents = svn.fs.dir_entries(root, dir_path)
    for name in dirents.keys():
      if not dirents[name].kind == svn.core.svn_node_dir:
        continue
      if pattern is None or sre.match(pattern, name):
        if dir_path == "":
          child_path = name
        else:
          child_path = "%s/%s" % (dir_path, name)
        if self.verbose:
          print "Examining path '%s' for conversion" % child_path
        if not self.convert_path_history(root, revnum, child_path):
          self.process_dir(root, revnum, child_path)

  def convert_path_history(self, root, revnum, path):
    "Migrate the merge history for PATH at ROOT at REVNUM."

    ### Bother to handle any pre-existing, inherited svn:mergeinfo?

    # Retrieve svnmerge.py's merge history meta data, and roll it into
    # Subversion 1.5 mergeinfo.
    mergeinfo_prop_val = svn.fs.node_prop(root, path,
                                          svn.core.SVN_PROP_MERGEINFO)
    integrated_prop_val = svn.fs.node_prop(root, path, "svnmerge-integrated")
    if self.verbose:
      print "Discovered pre-existing Subversion mergeinfo of '%s'" % \
        mergeinfo_prop_val
      print "Discovered svnmerge.py mergeinfo of '%s'" % integrated_prop_val
    mergeinfo_prop_val = self.add_to_mergeinfo(integrated_prop_val,
                                               mergeinfo_prop_val)
    ### LATER: We handle svnmerge-blocked by converting it into
    ### svn:mergeinfo, until revision blocking becomes available in
    ### Subversion's core.
    blocked_prop_val = svn.fs.node_prop(root, path, "svnmerge-blocked")
    if self.verbose:
      print "Discovered svnmerge.py blocked revisions of '%s'" % \
        blocked_prop_val
    mergeinfo_prop_val = self.add_to_mergeinfo(blocked_prop_val,
                                               mergeinfo_prop_val)

    if mergeinfo_prop_val is not None:
      # Begin a transaction in which we'll manipulate merge-related
      # properties.  Open the transaction root.
      txn = svn.fs.begin_txn2(self.fs, revnum, 0)
      root = svn.fs.txn_root(txn)

      # Manipulate the merge history.
      if self.verbose:
        print "Queuing change of %s to '%s'" % \
          (svn.core.SVN_PROP_MERGEINFO, mergeinfo_prop_val)
      svn.fs.change_node_prop(root, path, svn.core.SVN_PROP_MERGEINFO,
                              mergeinfo_prop_val)

      # Remove old property values.
      if integrated_prop_val is not None:
        if self.verbose:
          print "Queuing removal of svnmerge-integrated"
        svn.fs.change_node_prop(root, path, "svnmerge-integrated", None)
      if blocked_prop_val is not None:
        if self.verbose:
          print "Queuing removal of svnmerge-blocked"
        svn.fs.change_node_prop(root, path, "svnmerge-blocked", None)

      # Commit the transaction containing our property manipulation.
      if self.verbose:
        print "Committing the transaction containing the above changes"
      conflict, new_revnum = svn.fs.commit_txn(txn)
      if conflict:
        ### TODO: Do something more intelligent with the possible conflict.
        raise Exception("Conflict encountered (%s)" % conflict)
      print "Migrated merge history on '%s' in r%d" % (path, new_revnum)
      return True
    else:
      # No merge history to manipulate.
      if self.verbose:
        print "No merge history on '%s'" % path
      return False

  def add_to_mergeinfo(self, svnmerge_prop_val, mergeinfo_prop_val):
    if svnmerge_prop_val is not None:
      if mergeinfo_prop_val:
        mergeinfo = svn.core.svn_mergeinfo_parse(mergeinfo_prop_val)
        to_migrate = svn.core.svn_mergeinfo_parse(svnmerge_prop_val)
        mergeinfo = svn.core.svn_mergeinfo_merge(mergeinfo, to_migrate)
        mergeinfo_prop_val = svn.core.svn_mergeinfo_to_string(mergeinfo)
      else:
        mergeinfo_prop_val = svnmerge_prop_val

    return mergeinfo_prop_val

  def set_path_prefixes(self, prefixes):
    "Decompose path prefixes into something meaningful for comparision."
    self.path_prefixes = []
    for prefix in prefixes:
      prefix_components = []
      parts = prefix.split("/")
      for i in range(0, len(parts)):
        prefix_components.append(parts[i])
      self.path_prefixes.append(prefix_components)

def main():
  try:
    opts, args = my_getopt(sys.argv[1:], "vh?",
                           ["from-paths=", "verbose", "help"])
  except:
    usage_and_exit("Unable to process arguments/options")

  migrator = Migrator()

  # Process arguments.
  if len(args) >= 1:
    migrator.repos_path = svn.core.svn_path_canonicalize(args[0])
    if len(args) >= 2:
      path_prefixes = args[1:]
    else:
      # Default to the root of the repository.
      path_prefixes = [ "" ]
  else:
    usage_and_exit("REPOS_PATH argument required")

  # Process options.
  for opt, value in opts:
    if opt == "--help" or opt in ("-h", "-?"):
      usage_and_exit()
    elif opt == "--verbose" or opt == "-v":
      migrator.verbose = True
    else:
      usage_and_exit("Unknown option '%s'" % opt)

  migrator.set_path_prefixes(path_prefixes)
  migrator.run()

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


<commit_before>#!/bin/env python

import sys
import socket
from time import time
import json

import logging

import boto

def main(domain, key, deployment):
    sdbconn = boto.connect_sdb()
    maxtime = int(time()) + 5 * 60
    chef_attribs = json.load(open('/root/chef_attribs.json'))
    traits = chef_attribs.get('traits', [])
    if isinstance(traits, basestring):
        traits = [traits]

    lockr_attribs = dict(((_, key) for _ in traits))

    state = {}
    while 1:
        if not state.get('deregistered', False):
            try:
                r = sdbconn.delete_attributes(domain, key)
                if r is True:
                    state['deregistered'] = True
            except boto.exception.SDBResponseError, e:
                if e.status == 404:
                    state['deregistered'] = True
                else:
                    raise e
            except socket.gaierror, e:
                logging.warn("socket gaierror: %s" % (e,))
            except socket.error, e:
                logging.warn("socket error: %s" % (e,))

        if not state.get('unlocked', False):
            try:
                r = sdbconn.delete_attributes(domain, deployment, lockr_attribs)
                if r is True:
                    state['unlocked'] = True
            except boto.exception.SDBResponseError, e:
                if e.status == 404:
                    state['unlocked'] = True
                else:
                    raise e
            except socket.gaierror, e:
                logging.warn("socket gaierror: %s" % (e,))
            except socket.error, e:
                logging.warn("socket error: %s" % (e,))

        if state.get('unlocked', False) and state.get('deregistered', False):
            break

        if int(time()) > maxtime:
            logging.error("unable to succeed for 5 min - dying")
            sys.exit(1)

if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2])

<commit_msg>/bin/env doesn't exist, and forgot to get the last argument from the command line<commit_after>#!/usr/bin/env python

import sys
import socket
from time import time
import json

import logging

import boto

def main(domain, key, deployment):
    sdbconn = boto.connect_sdb()
    maxtime = int(time()) + 5 * 60
    chef_attribs = json.load(open('/root/chef_attribs.json'))
    traits = chef_attribs.get('traits', [])
    if isinstance(traits, basestring):
        traits = [traits]

    lockr_attribs = dict(((_, key) for _ in traits))

    state = {}
    while 1:
        if not state.get('deregistered', False):
            try:
                r = sdbconn.delete_attributes(domain, key)
                if r is True:
                    state['deregistered'] = True
            except boto.exception.SDBResponseError, e:
                if e.status == 404:
                    state['deregistered'] = True
                else:
                    raise e
            except socket.gaierror, e:
                logging.warn("socket gaierror: %s" % (e,))
            except socket.error, e:
                logging.warn("socket error: %s" % (e,))

        if not state.get('unlocked', False):
            try:
                r = sdbconn.delete_attributes(domain, deployment, lockr_attribs)
                if r is True:
                    state['unlocked'] = True
            except boto.exception.SDBResponseError, e:
                if e.status == 404:
                    state['unlocked'] = True
                else:
                    raise e
            except socket.gaierror, e:
                logging.warn("socket gaierror: %s" % (e,))
            except socket.error, e:
                logging.warn("socket error: %s" % (e,))

        if state.get('unlocked', False) and state.get('deregistered', False):
            break

        if int(time()) > maxtime:
            logging.error("unable to succeed for 5 min - dying")
            sys.exit(1)

if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2], sys.argv[3])

<|endoftext|>


<commit_before>from django.test import TestCase

from ..base import media_keys, comment_keys, keys
from ..utils import (
    get_responses,
    get_fields,
    get_mediafiles,
    get_info_comment,
    create_observation_row
)

class UtilsTest(TestCase):

    def setUp(self):

        self.data = [
        {
        'display_field':
            {'value': u'456565', 'key': u'name'},
        'media': [],
        'expiry_field': None,
        'comments': [
            [('id', 153),
                ('respondsto', None),
                ('created_at', u'2017-04-07T16:03:05.445019Z'),
                ('text', u'text_template1'),
                ('isowner', True),
                ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                ('review_status', None),
                ('responses', [
                    ('id', 155),
                    ('respondsto', None),
                    ('created_at', u'2017-04-07T16:03:10.005092Z'),
                    ('text', u'text_responses1'),
                    ('isowner', True),
                    ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                    ('review_status', None), ('responses', [])])],
            [('id', 154),
                ('respondsto', None),
                ('created_at', u'2017-04-07T16:03:10.005092Z'),
                ('text', u'text_template2'),
                ('isowner', True),
                ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                ('review_status', None), ('responses', [])
            ]
        ],
        'properties': {u'surname': u'pepepo5'},
        'meta':
            {
            'status': u'active',
            'num_media': 0,
            'isowner': True,
            'version': 1,
            'updator': None,
            'creator': {'display_name': u'c.grillo', 'id': 3},
            'num_comments': 1,
            'created_at': '2017-04-07 15:19:14.901149+00:00',
            'category':
                {
                'symbol': None,
                'colour': u'#0033ff',
                 'description': u'',
                 'id': 81,
                 'name': u'sinquerer'
                },
            'updated_at': '2017-04-07 15:19:14.901174+00:00'},
            'location':
                {
                'geometry': u'{ "type": "Point", "coordinates": [ -3.8671875, 15.792253570362446 ] }',
                'description': None,
                'id': 46,
                'name': None},
            'id': 41,

        }
        ]
        self.obs_id = self.data[0]['id']
        self.keys = keys
        self.comment_keys = comment_keys

    def test_get_fields(self):

        header = get_fields(self.data, self.keys)

        self.assertTrue('surname' in header)

    def test_get_info_comment(self):

        comments = {
            'id': 153,
            'respondsto': None,
            'created_at': u'2017-04-07T16:03:05.445019Z',
            'text': u'text_template1',
            'isowner': True,
            'creator': {'id': 3, 'display_name': u'c.grillo'},
            'review_status': None,
            'responses': {}
        }

        comment_txt = get_info_comment(33, comments, self.comment_keys)

        self.assertTrue(comments['text'] in comment_txt)
        self.assertTrue(str(comments['id']) in comment_txt)
        self.assertTrue(comments['creator']['display_name'] in comment_txt)
        self.assertTrue(str(comments['creator']['id']) in comment_txt)

    def test_get_responses(self):

        comments2 = {
            'id': 153,
            'respondsto': None,
            'created_at': u'2017-04-07T16:03:05.445019Z',
            'text': u'text_template1',
            'isowner': True,
            'creator': {'id': 3, 'display_name': u'c.grillo'},
            'review_status': None,
            'responses': [{
                'id': 555,
                'respondsto': 153,
                'created_at': u'2017-04-07T18:03:05.445019Z',
                'text': u'text_responses1',
                'isowner': True,
                'creator': {'id': 3, 'display_name': u'c.grillo_example'},
                'review_status': None,
                'responses': [{
                    'id': 232,
                    'respondsto': 555,
                    'created_at': u'2017-04-08T16:03:05.445019Z',
                    'text': u'text_responses11',
                    'isowner': True,
                    'creator': {'id': 3, 'display_name': u'c.grillo_test'},
                    'review_status': None,
                    'responses': {}
                }]
            }]

        }

        responses = get_responses(
            self.obs_id,
            comments2,
            1)

        comment_id = str(comments2['responses'][0]['id'])
        response_comment_id = str(comments2['responses'][0]['responses'][0]['id'])

        # self.assertTrue(str(comments['id']) in responses)
        self.assertEqual(2, len(responses))
        self.assertTrue(comment_id in responses[0])
        self.assertTrue(response_comment_id in responses[1])
        self.assertTrue(str('c.grillo_example') in responses[0])
        self.assertFalse(str('c.grillo_example') in responses[1])
        self.assertTrue(str('c.grillo_test') in responses[1])
        self.assertFalse(str('c.grillo_test') in responses[0])

    def test_create_observation_row(self):

        observation_txt = create_observation_row(self.data[0], self.keys)

        wkt_coordinates = 'POINT (-3.8671875000000000 15.7922535703624458)'
        display_name = self.data[0]['meta']['creator']['display_name']
        self.assertTrue(str(self.data[0]['id']) in observation_txt)
        self.assertTrue(wkt_coordinates in observation_txt)
        self.assertTrue(display_name in observation_txt)

    def test_get_mediafiles(self):

        mediafiles = [{
            "id": 86,
            "name": "django-neg.sh-600x600",
            "description": None,
            "created_at": "2017-04-05T15:25:18.576273Z",
            "creator": {
                "id": 3,
                "display_name": "c.gisbert123"
            },
            "isowner": True,
            "url": "http://127.0.0.1:8000/assets/user-uploads/images/django-negsh-600x600.png",
            "thumbnail_url": "http://127.0.0.1:8000/assets/user-uploads/images/django-negsh-600x600.png.300x300_q85_crop.png",
            "file_type": "ImageFile"
        }, {
            "id": 87,
            "name": "costa",
            "description": None,
            "created_at": "2017-04-05T15:25:19.105646Z",
            "creator": {
                "id": 3,
                "display_name": "c.gisbert123"
            },
            "isowner": True,
            "url": "http://127.0.0.1:8000/assets/user-uploads/images/costa.png",
            "thumbnail_url": "http://127.0.0.1:8000/assets/user-uploads/images/costa.png.300x300_q85_crop.jpg",
            "file_type": "ImageFile"
        }]

        mediafiles_txt = get_mediafiles(
            self.obs_id,
            mediafiles[0],
            media_keys)
        print "mediafiles_txt", mediafiles_txt
        self.assertTrue(str(mediafiles[0]['id']) in mediafiles_txt)
        self.assertTrue(mediafiles[0]['url'] in mediafiles_txt)
        self.assertFalse(mediafiles[1]['url'] in mediafiles_txt)
        self.assertTrue(mediafiles[0]['file_type'] in mediafiles_txt)
        self.assertFalse('VideoFile' in mediafiles_txt)

        mediafiles_txt2 = get_mediafiles(
            self.obs_id,
            mediafiles[1],
            media_keys)

        print "mediafiles_txt2", mediafiles_txt
        self.assertTrue(str(mediafiles[1]['id']) in mediafiles_txt2)
        self.assertTrue(mediafiles[1]['url'] in mediafiles_txt2)
        self.assertFalse(mediafiles[0]['url'] in mediafiles_txt2)
        self.assertTrue(mediafiles[1]['file_type'] in mediafiles_txt2)
        self.assertFalse('VideoFile' in mediafiles_txt2)

<commit_msg>DocStrings for test_utils<commit_after>from django.test import TestCase

from ..base import media_keys, comment_keys, keys
from ..utils import (
    get_responses,
    get_fields,
    get_mediafiles,
    get_info_comment,
    create_observation_row
)

class UtilsTest(TestCase):

    def setUp(self):

        self.data = [
        {
        'display_field':
            {'value': u'456565', 'key': u'name'},
        'media': [],
        'expiry_field': None,
        'comments': [
            [('id', 153),
                ('respondsto', None),
                ('created_at', u'2017-04-07T16:03:05.445019Z'),
                ('text', u'text_template1'),
                ('isowner', True),
                ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                ('review_status', None),
                ('responses', [
                    ('id', 155),
                    ('respondsto', None),
                    ('created_at', u'2017-04-07T16:03:10.005092Z'),
                    ('text', u'text_responses1'),
                    ('isowner', True),
                    ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                    ('review_status', None), ('responses', [])])],
            [('id', 154),
                ('respondsto', None),
                ('created_at', u'2017-04-07T16:03:10.005092Z'),
                ('text', u'text_template2'),
                ('isowner', True),
                ('creator', [('id', 3), ('display_name', u'c.grillo')]),
                ('review_status', None), ('responses', [])
            ]
        ],
        'properties': {u'country': u'Island'},
        'meta':
            {
            'status': u'active',
            'num_media': 0,
            'isowner': True,
            'version': 1,
            'updator': None,
            'creator': {'display_name': u'c.grillo', 'id': 3},
            'num_comments': 1,
            'created_at': '2017-04-07 15:19:14.901149+00:00',
            'category':
                {
                'symbol': None,
                'colour': u'#0033ff',
                 'description': u'',
                 'id': 81,
                 'name': u'sinquerer'
                },
            'updated_at': '2017-04-07 15:19:14.901174+00:00'},
            'location':
                {
                'geometry': u'{ "type": "Point", "coordinates": [ -3.8671875, 15.792253570362446 ] }',
                'description': None,
                'id': 46,
                'name': None},
            'id': 41,

        }
        ]
        self.obs_id = self.data[0]['id']
        self.keys = keys
        self.comment_keys = comment_keys

    def test_get_fields(self):
        """Test for get_fields method."""
        headers = get_fields(self.data, self.keys)

        self.assertTrue('country' in headers)

    def test_get_info_comment(self):
        """Test for get_info_method."""
        comments = {
            'id': 153,
            'respondsto': None,
            'created_at': u'2017-04-07T16:03:05.445019Z',
            'text': u'text_template1',
            'isowner': True,
            'creator': {'id': 3, 'display_name': u'c.grillo'},
            'review_status': None,
            'responses': {}
        }

        comment_txt = get_info_comment(33, comments, self.comment_keys)

        self.assertTrue(comments['text'] in comment_txt)
        self.assertTrue(str(comments['id']) in comment_txt)
        self.assertTrue(comments['creator']['display_name'] in comment_txt)
        self.assertTrue(str(comments['creator']['id']) in comment_txt)

    def test_get_responses(self):
        """Test for get_responses."""
        comments2 = {
            'id': 153,
            'respondsto': None,
            'created_at': u'2017-04-07T16:03:05.445019Z',
            'text': u'text_template1',
            'isowner': True,
            'creator': {'id': 3, 'display_name': u'c.grillo'},
            'review_status': None,
            'responses': [{
                'id': 555,
                'respondsto': 153,
                'created_at': u'2017-04-07T18:03:05.445019Z',
                'text': u'text_responses1',
                'isowner': True,
                'creator': {'id': 3, 'display_name': u'c.grillo_example'},
                'review_status': None,
                'responses': [{
                    'id': 232,
                    'respondsto': 555,
                    'created_at': u'2017-04-08T16:03:05.445019Z',
                    'text': u'text_responses11',
                    'isowner': True,
                    'creator': {'id': 3, 'display_name': u'c.grillo_test'},
                    'review_status': None,
                    'responses': {}
                }]
            }]

        }

        responses = get_responses(
            self.obs_id,
            comments2,
            1)

        comment_id = str(comments2['responses'][0]['id'])
        response_comment_id = str(comments2['responses'][0]['responses'][0]['id'])

        # self.assertTrue(str(comments['id']) in responses)
        self.assertEqual(2, len(responses))
        self.assertTrue(comment_id in responses[0])
        self.assertTrue(response_comment_id in responses[1])
        self.assertTrue(str('c.grillo_example') in responses[0])
        self.assertFalse(str('c.grillo_example') in responses[1])
        self.assertTrue(str('c.grillo_test') in responses[1])
        self.assertFalse(str('c.grillo_test') in responses[0])

    def test_create_observation_row(self):
        """Test for create_observation_row."""
        observation_txt = create_observation_row(self.data[0], self.keys)

        wkt_coordinates = 'POINT (-3.8671875000000000 15.7922535703624458)'
        display_name = self.data[0]['meta']['creator']['display_name']
        self.assertTrue(str(self.data[0]['id']) in observation_txt)
        self.assertTrue(wkt_coordinates in observation_txt)
        self.assertTrue(display_name in observation_txt)

    def test_get_mediafiles(self):
        """Test for get_mediafiles."""

        mediafiles = [{
            "id": 86,
            "name": "django-neg.sh-600x600",
            "description": None,
            "created_at": "2017-04-05T15:25:18.576273Z",
            "creator": {
                "id": 3,
                "display_name": "c.gisbert123"
            },
            "isowner": True,
            "url": "http://127.0.0.1:8000/assets/user-uploads/images/django-negsh-600x600.png",
            "thumbnail_url": "http://127.0.0.1:8000/assets/user-uploads/images/django-negsh-600x600.png.300x300_q85_crop.png",
            "file_type": "ImageFile"
        }, {
            "id": 87,
            "name": "costa",
            "description": None,
            "created_at": "2017-04-05T15:25:19.105646Z",
            "creator": {
                "id": 3,
                "display_name": "c.gisbert123"
            },
            "isowner": True,
            "url": "http://127.0.0.1:8000/assets/user-uploads/images/costa.png",
            "thumbnail_url": "http://127.0.0.1:8000/assets/user-uploads/images/costa.png.300x300_q85_crop.jpg",
            "file_type": "ImageFile"
        }]

        mediafiles_txt = get_mediafiles(
            self.obs_id,
            mediafiles[0],
            media_keys)

        self.assertTrue(str(mediafiles[0]['id']) in mediafiles_txt)
        self.assertTrue(mediafiles[0]['url'] in mediafiles_txt)
        self.assertFalse(mediafiles[1]['url'] in mediafiles_txt)
        self.assertTrue(mediafiles[0]['file_type'] in mediafiles_txt)
        self.assertFalse('VideoFile' in mediafiles_txt)

        mediafiles_txt2 = get_mediafiles(
            self.obs_id,
            mediafiles[1],
            media_keys)

        self.assertTrue(str(mediafiles[1]['id']) in mediafiles_txt2)
        self.assertTrue(mediafiles[1]['url'] in mediafiles_txt2)
        self.assertFalse(mediafiles[0]['url'] in mediafiles_txt2)
        self.assertTrue(mediafiles[1]['file_type'] in mediafiles_txt2)
        self.assertFalse('VideoFile' in mediafiles_txt2)

<|endoftext|>


<commit_before>from django import template
import time
import os

register = template.Library()

@register.simple_tag
def version_date():
    try:
        timestamp = "Updated: " + time.strftime('%m/%d/%Y', time.gmtime(os.path.getmtime('.git')))
    except:
        timestamp = ""
    return timestamp

__version__ = "2.0"

@register.simple_tag
def version_number():

    return  "Version: " + __version__

<commit_msg>bump version<commit_after>from django import template
import time
import os

register = template.Library()

@register.simple_tag
def version_date():
    try:
        timestamp = "Updated: " + time.strftime('%m/%d/%Y', time.gmtime(os.path.getmtime('.git')))
    except:
        timestamp = ""
    return timestamp

__version__ = "2.1"

@register.simple_tag
def version_number():

    return  "Version: " + __version__

<|endoftext|>


<commit_before>from django.contrib import admin

from modeltranslation.admin import TranslationAdmin

from data_request.models import DataRequest, AuthenticationContent
from data_request.models import FaqContent, RequestContent

@admin.register(RequestContent)
class RequestContentAdmin(TranslationAdmin):
    list_display = ['title']

@admin.register(FaqContent)
class FaqContentAdmin(TranslationAdmin):
    list_display = ['title', 'priority']

@admin.register(RequestContent)
class RequestContentAdmin(admin.ModelAdmin):
    list_display = ["title"]

@admin.register(FaqContent)
class FaqContentAdmin(TranslationAdmin):
    list_display = ['title', 'priority']
<commit_msg>Remove duplicate code<commit_after>from django.contrib import admin

from modeltranslation.admin import TranslationAdmin

from data_request.models import DataRequest, AuthenticationContent
from data_request.models import FaqContent, RequestContent

@admin.register(RequestContent)
class RequestContentAdmin(TranslationAdmin):
    list_display = ['title']

@admin.register(FaqContent)
class FaqContentAdmin(TranslationAdmin):
    list_display = ['title', 'priority']
<|endoftext|>


<commit_before>from Products.CMFCore.utils import getToolByName
from Products.CMFCore import permissions
from bika.lims.permissions import AddSupplyOrder

def ObjectModifiedEventHandler(obj, event):
    """ Various types need automation on edit.
    """
    if not hasattr(obj, 'portal_type'):
        return

    if obj.portal_type == 'Calculation':
        pr = getToolByName(obj, 'portal_repository')
        uc = getToolByName(obj, 'uid_catalog')
        obj = uc(UID=obj.UID())[0].getObject()
        backrefs = obj.getBackReferences('AnalysisServiceCalculation')
        for i, service in enumerate(backrefs):
            service = uc(UID=service.UID())[0].getObject()
            pr.save(obj=service, comment="Calculation updated to version %s" %
                (obj.version_id + 1,))
            reference_versions = getattr(service, 'reference_versions', {})
            reference_versions[obj.UID()] = obj.version_id + 1
            service.reference_versions = reference_versions

    elif obj.portal_type == 'Client':
        mp = obj.manage_permission
        mp(permissions.ListFolderContents, ['Manager', 'LabManager', 'LabClerk', 'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)
        mp(permissions.View, ['Manager', 'LabManager', 'LabClerk',  'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)
        mp(permissions.ModifyPortalContent, ['Manager', 'LabManager', 'Owner'], 0)
        mp(AddSupplyOrder, ['Manager', 'LabManager', 'Owner'], 0)
        mp('Access contents information', ['Manager', 'LabManager', 'Member', 'LabClerk', 'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)

    elif obj.portal_type == 'Contact':
        mp = obj.manage_permission
        mp(permissions.View, ['Manager', 'LabManager', 'LabClerk', 'Owner', 'Analyst', 'Sampler', 'Preserver'], 0)
        mp(permissions.ModifyPortalContent, ['Manager', 'LabManager', 'Owner'], 0)
<commit_msg>LIMS-83: Update Method when Calculation changes<commit_after>from Products.CMFCore.utils import getToolByName
from Products.CMFCore import permissions
from bika.lims.permissions import AddSupplyOrder

def ObjectModifiedEventHandler(obj, event):
    """ Various types need automation on edit.
    """
    if not hasattr(obj, 'portal_type'):
        return

    if obj.portal_type == 'Calculation':
        pr = getToolByName(obj, 'portal_repository')
        uc = getToolByName(obj, 'uid_catalog')
        obj = uc(UID=obj.UID())[0].getObject()

        backrefs = obj.getBackReferences('AnalysisServiceCalculation')
        for i, target in enumerate(backrefs):
            target = uc(UID=target.UID())[0].getObject()
            pr.save(obj=target, comment="Calculation updated to version %s" %
                (obj.version_id + 1,))
            reference_versions = getattr(target, 'reference_versions', {})
            reference_versions[obj.UID()] = obj.version_id + 1
            target.reference_versions = reference_versions

        backrefs = obj.getBackReferences('MethodCalculation')
        for i, target in enumerate(backrefs):
            target = uc(UID=target.UID())[0].getObject()
            pr.save(obj=target, comment="Calculation updated to version %s" %
                (obj.version_id + 1,))
            reference_versions = getattr(target, 'reference_versions', {})
            reference_versions[obj.UID()] = obj.version_id + 1
            target.reference_versions = reference_versions

    elif obj.portal_type == 'Client':
        mp = obj.manage_permission
        mp(permissions.ListFolderContents, ['Manager', 'LabManager', 'LabClerk', 'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)
        mp(permissions.View, ['Manager', 'LabManager', 'LabClerk',  'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)
        mp(permissions.ModifyPortalContent, ['Manager', 'LabManager', 'Owner'], 0)
        mp(AddSupplyOrder, ['Manager', 'LabManager', 'Owner'], 0)
        mp('Access contents information', ['Manager', 'LabManager', 'Member', 'LabClerk', 'Analyst', 'Sampler', 'Preserver', 'Owner'], 0)

    elif obj.portal_type == 'Contact':
        mp = obj.manage_permission
        mp(permissions.View, ['Manager', 'LabManager', 'LabClerk', 'Owner', 'Analyst', 'Sampler', 'Preserver'], 0)
        mp(permissions.ModifyPortalContent, ['Manager', 'LabManager', 'Owner'], 0)
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
#3> <> prov:wasRevisionOf
#3>    <https://github.com/jimmccusker/twc-healthdata/blob/master/ckan/mirror.py> .
#
# Invoke from a cr:source directory, e.g. source/hub-healthdata-gov
#   % cr-pwd.sh
#     source/hub-healthdata-gov
#   % cr-create-dataset-dirs-from-ckan.py http://healthdata.tw.rpi.edu/hub/api \
#                                         http://purl.org/twc/health \
#                                         http://hub.healthdata.gov
#   % find . -name dcat.ttl | xargs git add -f

import sys, os, re, json, uuid, hashlib

import ckanclient  # see README at https://github.com/okfn/ckanclient
# Get latest download URL \/ from http://pypi.python.org/pypi/ckanclient#downloads
# sudo easy_install http://pypi.python.org/packages/source/c/ckanclient/ckanclient-0.10.tar.gz

# See also https://github.com/timrdf/DataFAQs/wiki/CKAN
#    section "Automatically publish dataset on CKAN"

if len(sys.argv) <= 2 or (len(sys.argv) > 1 and sys.argv[1] == "--help"):
   print
   print "usage: %s <ckan-api> <CSV2RDF4LOD_BASE_URI>: [mirrored-ckan]" % os.path.basename(sys.argv[0])
   print
   print "  <ckan-api>:             The API URL for the CKAN instance."
   print "                          e.g. http://healthdata.tw.rpi.edu/hub/api"
   print "  <CSV2RDF4LOD_BASE_URI>: The base URI of the VoID datasets that will be created from CKAN."
   print "                          e.g. http://purl.org/twc/health"
   print "  [mirrored-ckan]:        The original CKAN instance being mirrored by <ckan-api>."
   print "                          OPTIONAL: if omitted, will omit some PROV assertions."
   print "                          e.g. http://hub.healthdata.gov"
   print
   print "  must be run from a cr:source directory (e.g. /srv/twc-healthdata/data/source/hub-healthdata-gov)"
   print "    (see https://github.com/timrdf/csv2rdf4lod-automation/wiki/directory%20conventions)"
   print
   sys.exit(1)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                # http://hub.healthdata.gov/api
ckanAPI              = sys.argv[1]                              # http://healthdata.tw.rpi.edu/hub/api
CSV2RDF4LOD_BASE_URI = sys.argv[2]                              # http://purl.org/twc/health
mirroredCKAN         = sys.argv[3] if len(sys.argv) > 3 else '' # http://hub.healthdata.gov/dataset/
sourceID             = os.path.basename(os.getcwd())            # hub-healthdata-gov

# Focus on formats?
focusOnFormats = False          # Set to False to get retrieval info about all datasets.
desiredFormats = ['CSV', 'XLS'] # Applies only when focusOnFormats == True
# Formats seen on healthdata.gov:
#    CSV Text XLS XML Feed Query API Widget RDF
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#print "ckan-api:  " + ckanAPI
#print "SOURCE-ID: " + sourceID
#print "BASE_URI:  " + CSV2RDF4LOD_BASE_URI
#sys.exit(1)

ckan = ckanclient.CkanClient(base_location=ckanAPI)

indent = '    '
for name in ckan.package_register_get():

   ckan.package_entity_get(name) # Get the dataset description.
   dataset = ckan.last_message

   URL = ''
   fmt = ''
   desiredFormat = False
   for resource in dataset['resources']:
      if (not desiredFormat and
         'url'    in resource and len(str(resource['url'])) > 0 and
        ('format' in resource and resource['format'].upper() in desiredFormats or not(focusOnFormats))):
         desiredFormat = True
         URL = resource['url']
         fmt = resource['format']
         print indent + 'resource:     ' + resource['format'] + ' ' + resource['url']
   if name == 'hospital-compare' and False:
      if 'download_url' in dataset:
         print indent + 'download_url: ' + dataset['download_url']
      if 'url' in dataset:
         print indent + 'url:          ' + dataset['url']
      print json.dumps(dataset,sort_keys=True, indent=4)

   if desiredFormat:
      replacements = {
         'CSV2RDF4LOD_BASE_URI' : CSV2RDF4LOD_BASE_URI,
         'SOURCE_ID'            : sourceID,
         'DATASET_ID'           : dataset['name'],
         'FORMAT'               : fmt.replace(' ','_'),
         'UUID'                 : str(uuid.uuid4()),
         'SOURCE_CKAN'          : ckanAPI.replace('/api',''),
         'SOURCE_AGENT'         : re.sub('(http://[^/]*)/.*$','\\1',ckanAPI),
         'DIST_URL'             : URL,
         'MIRRORED_CKAN'        : mirroredCKAN,
         'MIRRORED_AGENT'       : re.sub('(http://[^/]*)/.*$','\\1',mirroredCKAN),
      }

      m = hashlib.md5()
      m.update(replacements['CSV2RDF4LOD_BASE_URI'] +
               replacements['SOURCE_ID'] +
               replacements['DATASET_ID'] +
               fmt +
               replacements['DIST_URL'])
      replacements['UUID'] = m.hexdigest()

      template='''@prefix rdfs:       <http://www.w3.org/2000/01/rdf-schema#> .
@prefix conversion: <http://purl.org/twc/vocab/conversion/> .
@prefix dcat:       <http://www.w3.org/ns/dcat#> .
@prefix void:       <http://rdfs.org/ns/void#> .
@prefix prov:       <http://www.w3.org/ns/prov#> .
@prefix datafaqs:   <http://purl.org/twc/vocab/datafaqs#> .
@prefix :           <CSV2RDF4LOD_BASE_URI/id/> .

<CSV2RDF4LOD_BASE_URI/source/SOURCE_ID/dataset/DATASET_ID>
   a void:Dataset, dcat:Dataset;
   conversion:source_identifier  "SOURCE_ID";
   conversion:dataset_identifier "DATASET_ID";
   prov:wasDerivedFrom :as_a_csv_UUID;
.

:as_a_FORMAT_UUID
   a dcat:Distribution;
   dcat:downloadURL <DIST_URL>;
.

<SOURCE_CKAN/dataset/DATASET_ID>
   a dcat:Dataset, datafaqs:CKANDataset;
   dcat:distribution :as_a_csv_UUID;
   prov:wasAttributedTo <SOURCE_AGENT>;
.
'''
      if len(mirroredCKAN) > 0:
         template = template + '''
<SOURCE_CKAN/dataset/DATASET_ID>
   prov:alternateOf <MIRRORED_CKAN/dataset/DATASET_ID>;
.

<MIRRORED_CKAN/dataset/DATASET_ID>
   a dcat:Dataset, datafaqs:CKANDataset;
   prov:alternateOf <SOURCE_CKAN/dataset/DATASET_ID>;
   prov:wasAttributedTo <MIRRORED_AGENT>;
.
'''
      template = template + '''
#3> <> prov:wasGeneratedBy [
#3>    a prov:Activity;
#3>    prov:qualifiedAssociation [
#3>       a prov:Association;
#3>       prov:hadPlan <https://github.com/timrdf/csv2rdf4lod-automation/blob/master/bin/cr-create-dataset-dirs-from-ckan.py>;
#3>    ];
#3>    rdfs:seeAlso <https://github.com/jimmccusker/twc-healthdata/wiki/Accessing-CKAN-listings>;
#3> ] .
#3> <https://github.com/timrdf/csv2rdf4lod-automation/blob/master/bin/cr-create-dataset-dirs-from-ckan.py>
#3>    a prov:Plan;
#3>    dcterms:title "'''+os.path.basename(sys.argv[0])+'''" ;
#3> .
'''
      for search in replacements.keys():
         template = template.replace(search,replacements[search])

      filename = dataset['name']+'/dcat.ttl'
      if not os.path.exists(dataset['name']):
         os.makedirs(dataset['name'])
      print filename
      f = open(filename, 'w')
      f.write(template)
      f.close()
<commit_msg>hashing distributions<commit_after>#!/usr/bin/env python
#
#3> <> prov:wasRevisionOf
#3>    <https://github.com/jimmccusker/twc-healthdata/blob/master/ckan/mirror.py> .
#
# Invoke from a cr:source directory, e.g. source/hub-healthdata-gov
#   % cr-pwd.sh
#     source/hub-healthdata-gov
#   % cr-create-dataset-dirs-from-ckan.py http://healthdata.tw.rpi.edu/hub/api \
#                                         http://purl.org/twc/health \
#                                         http://hub.healthdata.gov
#   % find . -name dcat.ttl | xargs git add -f

import sys, os, re, json, uuid, hashlib

import ckanclient  # see README at https://github.com/okfn/ckanclient
# Get latest download URL \/ from http://pypi.python.org/pypi/ckanclient#downloads
# sudo easy_install http://pypi.python.org/packages/source/c/ckanclient/ckanclient-0.10.tar.gz

# See also https://github.com/timrdf/DataFAQs/wiki/CKAN
#    section "Automatically publish dataset on CKAN"

if len(sys.argv) <= 2 or (len(sys.argv) > 1 and sys.argv[1] == "--help"):
   print
   print "usage: %s <ckan-api> <CSV2RDF4LOD_BASE_URI>: [mirrored-ckan]" % os.path.basename(sys.argv[0])
   print
   print "  <ckan-api>:             The API URL for the CKAN instance."
   print "                          e.g. http://healthdata.tw.rpi.edu/hub/api"
   print "  <CSV2RDF4LOD_BASE_URI>: The base URI of the VoID datasets that will be created from CKAN."
   print "                          e.g. http://purl.org/twc/health"
   print "  [mirrored-ckan]:        The original CKAN instance being mirrored by <ckan-api>."
   print "                          OPTIONAL: if omitted, will omit some PROV assertions."
   print "                          e.g. http://hub.healthdata.gov"
   print
   print "  must be run from a cr:source directory (e.g. /srv/twc-healthdata/data/source/hub-healthdata-gov)"
   print "    (see https://github.com/timrdf/csv2rdf4lod-automation/wiki/directory%20conventions)"
   print
   sys.exit(1)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                # http://hub.healthdata.gov/api
ckanAPI              = sys.argv[1]                              # http://healthdata.tw.rpi.edu/hub/api
CSV2RDF4LOD_BASE_URI = sys.argv[2]                              # http://purl.org/twc/health
mirroredCKAN         = sys.argv[3] if len(sys.argv) > 3 else '' # http://hub.healthdata.gov/dataset/
sourceID             = os.path.basename(os.getcwd())            # hub-healthdata-gov

# Focus on formats?
focusOnFormats = False          # Set to False to get retrieval info about all datasets.
desiredFormats = ['CSV', 'XLS'] # Applies only when focusOnFormats == True
# Formats seen on healthdata.gov:
#    CSV Text XLS XML Feed Query API Widget RDF
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#print "ckan-api:  " + ckanAPI
#print "SOURCE-ID: " + sourceID
#print "BASE_URI:  " + CSV2RDF4LOD_BASE_URI
#sys.exit(1)

ckan = ckanclient.CkanClient(base_location=ckanAPI)

indent = '    '
for name in ckan.package_register_get():

   ckan.package_entity_get(name) # Get the dataset description.
   dataset = ckan.last_message

   URL = ''
   fmt = ''
   desiredFormat = False
   for resource in dataset['resources']:
      if (not desiredFormat and
         'url'    in resource and len(str(resource['url'])) > 0 and
        ('format' in resource and resource['format'].upper() in desiredFormats or not(focusOnFormats))):
         desiredFormat = True
         URL = resource['url']
         fmt = resource['format']
         print indent + 'resource:     ' + resource['format'] + ' ' + resource['url']
   if name == 'hospital-compare' and False:
      if 'download_url' in dataset:
         print indent + 'download_url: ' + dataset['download_url']
      if 'url' in dataset:
         print indent + 'url:          ' + dataset['url']
      print json.dumps(dataset,sort_keys=True, indent=4)

   if desiredFormat:
      replacements = {
         'CSV2RDF4LOD_BASE_URI' : CSV2RDF4LOD_BASE_URI,
         'SOURCE_ID'            : sourceID,
         'DATASET_ID'           : dataset['name'],
         'FORMAT'               : fmt.replace(' ','_').lower(),
         'UUID'                 : str(uuid.uuid4()),
         'SOURCE_CKAN'          : ckanAPI.replace('/api',''),
         'SOURCE_AGENT'         : re.sub('(http://[^/]*)/.*$','\\1',ckanAPI),
         'DIST_URL'             : URL,
         'MIRRORED_CKAN'        : mirroredCKAN,
         'MIRRORED_AGENT'       : re.sub('(http://[^/]*)/.*$','\\1',mirroredCKAN),
      }

      m = hashlib.md5()
      m.update(replacements['CSV2RDF4LOD_BASE_URI'] +
               replacements['SOURCE_ID'] +
               replacements['DATASET_ID'] +
               fmt +
               replacements['DIST_URL'])
      replacements['UUID'] = m.hexdigest()

      template='''@prefix rdfs:       <http://www.w3.org/2000/01/rdf-schema#> .
@prefix conversion: <http://purl.org/twc/vocab/conversion/> .
@prefix dcat:       <http://www.w3.org/ns/dcat#> .
@prefix void:       <http://rdfs.org/ns/void#> .
@prefix prov:       <http://www.w3.org/ns/prov#> .
@prefix datafaqs:   <http://purl.org/twc/vocab/datafaqs#> .
@prefix :           <CSV2RDF4LOD_BASE_URI/id/> .

<CSV2RDF4LOD_BASE_URI/source/SOURCE_ID/dataset/DATASET_ID>
   a void:Dataset, dcat:Dataset;
   conversion:source_identifier  "SOURCE_ID";
   conversion:dataset_identifier "DATASET_ID";
   prov:wasDerivedFrom :as_a_FORMAT_UUID;
.

:as_a_FORMAT_UUID
   a dcat:Distribution;
   dcat:downloadURL <DIST_URL>;
.

<SOURCE_CKAN/dataset/DATASET_ID>
   a dcat:Dataset, datafaqs:CKANDataset;
   dcat:distribution :as_a_csv_UUID;
   prov:wasAttributedTo <SOURCE_AGENT>;
.
'''
      if len(mirroredCKAN) > 0:
         template = template + '''
<SOURCE_CKAN/dataset/DATASET_ID>
   prov:alternateOf <MIRRORED_CKAN/dataset/DATASET_ID>;
.

<MIRRORED_CKAN/dataset/DATASET_ID>
   a dcat:Dataset, datafaqs:CKANDataset;
   prov:alternateOf <SOURCE_CKAN/dataset/DATASET_ID>;
   prov:wasAttributedTo <MIRRORED_AGENT>;
.
'''
      template = template + '''
#3> <> prov:wasGeneratedBy [
#3>    a prov:Activity;
#3>    prov:qualifiedAssociation [
#3>       a prov:Association;
#3>       prov:hadPlan <https://github.com/timrdf/csv2rdf4lod-automation/blob/master/bin/cr-create-dataset-dirs-from-ckan.py>;
#3>    ];
#3>    rdfs:seeAlso <https://github.com/jimmccusker/twc-healthdata/wiki/Accessing-CKAN-listings>;
#3> ] .
#3> <https://github.com/timrdf/csv2rdf4lod-automation/blob/master/bin/cr-create-dataset-dirs-from-ckan.py>
#3>    a prov:Plan;
#3>    dcterms:title "'''+os.path.basename(sys.argv[0])+'''" ;
#3> .
'''
      for search in replacements.keys():
         template = template.replace(search,replacements[search])

      filename = dataset['name']+'/dcat.ttl'
      if not os.path.exists(dataset['name']):
         os.makedirs(dataset['name'])
      print filename
      f = open(filename, 'w')
      f.write(template)
      f.close()
<|endoftext|>