mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-16 18:46:27 +02:00
[core] String formatting of parameters with/without quotes to deal with spaces in strings
We have the problem of spaces in file paths, choices (like colorspace), etc. An empty list is not send to the command line. An empty string is send to the command line as "". Add new unit test to ensure it follows the expected rules.
This commit is contained in:
parent
1141d44bce
commit
a7fc167512
3 changed files with 98 additions and 7 deletions
|
@ -305,15 +305,31 @@ class Attribute(BaseObject):
|
|||
return self._value
|
||||
|
||||
def getEvalValue(self):
|
||||
'''
|
||||
Return the value. If it is a string, expressions will be evaluated.
|
||||
'''
|
||||
if isinstance(self.value, str):
|
||||
return Template(self.value).safe_substitute(os.environ)
|
||||
return self.value
|
||||
|
||||
def getValueStr(self):
|
||||
'''
|
||||
Return the value formatted as a string with quotes to deal with spaces.
|
||||
If it is a string, expressions will be evaluated.
|
||||
If it is an empty string, it will returns 2 quotes.
|
||||
If it is an empty list, it will returns a really empty string.
|
||||
If it is a list with one empty string element, it will returns 2 quotes.
|
||||
'''
|
||||
# ChoiceParam with multiple values should be combined
|
||||
if isinstance(self.attributeDesc, desc.ChoiceParam) and not self.attributeDesc.exclusive:
|
||||
# ensure value is a list as expected
|
||||
assert(isinstance(self.value, Sequence) and not isinstance(self.value, str))
|
||||
return self.attributeDesc.joinChar.join(self.getEvalValue())
|
||||
if isinstance(self.attributeDesc, (desc.StringParam, desc.File)):
|
||||
v = self.attributeDesc.joinChar.join(self.getEvalValue())
|
||||
if v:
|
||||
return '"{}"'.format(v)
|
||||
return v
|
||||
# String, File, single value Choice are based on strings and should includes quotes to deal with spaces
|
||||
if isinstance(self.attributeDesc, (desc.StringParam, desc.File, desc.ChoiceParam)):
|
||||
return '"{}"'.format(self.getEvalValue())
|
||||
return str(self.getEvalValue())
|
||||
|
||||
|
@ -498,9 +514,8 @@ class ListAttribute(Attribute):
|
|||
return [attr.getPrimitiveValue(exportDefault=exportDefault) for attr in self._value if not attr.isDefault]
|
||||
|
||||
def getValueStr(self):
|
||||
if isinstance(self.value, ListModel):
|
||||
assert(isinstance(self.value, ListModel))
|
||||
return self.attributeDesc.joinChar.join([v.getValueStr() for v in self.value])
|
||||
return super(ListAttribute, self).getValueStr()
|
||||
|
||||
def updateInternals(self):
|
||||
super(ListAttribute, self).updateInternals()
|
||||
|
|
|
@ -711,8 +711,12 @@ class BaseNode(BaseObject):
|
|||
# if there is a valid command line "group"
|
||||
v = attr.getValueStr()
|
||||
cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
|
||||
cmdVars[name + 'Value'] = str(v)
|
||||
cmdVars[name + 'Value'] = v
|
||||
|
||||
# List elements may give a fully empty string and will not be sent to the command line.
|
||||
# String attributes will return only quotes if it is empty and thus will be send to the command line.
|
||||
# But a List of string containing 1 element,
|
||||
# and this element is an empty string will also return quotes and will be send to the command line.
|
||||
if v:
|
||||
cmdVars[group] = cmdVars.get(group, '') + ' ' + cmdVars[name]
|
||||
elif isinstance(attr, GroupAttribute):
|
||||
|
@ -762,7 +766,7 @@ class BaseNode(BaseObject):
|
|||
v = attr.getValueStr()
|
||||
|
||||
self._cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
|
||||
self._cmdVars[name + 'Value'] = str(v)
|
||||
self._cmdVars[name + 'Value'] = v
|
||||
|
||||
if v:
|
||||
self._cmdVars[attr.attributeDesc.group] = self._cmdVars.get(attr.attributeDesc.group, '') + \
|
||||
|
|
72
tests/test_nodeCommandLineFormatting.py
Normal file
72
tests/test_nodeCommandLineFormatting.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf-8
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import meshroom.multiview
|
||||
from meshroom.core.graph import Graph
|
||||
from meshroom.core.node import Node
|
||||
|
||||
|
||||
def test_formatting_listOfFiles():
|
||||
inputImages = ['/non/existing/fileA', '/non/existing/with space/fileB']
|
||||
|
||||
graph = Graph('')
|
||||
n1 = graph.addNewNode('CameraInit')
|
||||
n1.viewpoints.extend([{'path': image} for image in inputImages])
|
||||
# viewId, poseId, path, intrinsicId, rigId, subPoseId, metadata
|
||||
assert n1.viewpoints.getValueStr() == '-1 -1 "/non/existing/fileA" -1 -1 -1 "" -1 -1 "/non/existing/with space/fileB" -1 -1 -1 ""'
|
||||
|
||||
assert n1.allowedCameraModels.getValueStr() == '"pinhole,radial1,radial3,brown,fisheye4,fisheye1,3deanamorphic4,3deradial4,3declassicld"'
|
||||
|
||||
graph = Graph('')
|
||||
n1 = graph.addNewNode('ImageMatching')
|
||||
assert n1.featuresFolders.getValueStr() == ''
|
||||
|
||||
n1.featuresFolders.extend("single value with space")
|
||||
assert n1.featuresFolders.getValueStr() == '"single value with space"'
|
||||
|
||||
n1.featuresFolders.resetValue()
|
||||
assert n1.featuresFolders.getValueStr() == ''
|
||||
|
||||
value = '"/non/existing/fileA" "/non/existing/with space/fileB"'
|
||||
n1.featuresFolders.extend(inputImages)
|
||||
assert n1.featuresFolders.getValueStr() == value
|
||||
|
||||
n1._buildCmdVars() # prepare vars for command line creation
|
||||
# and check some values
|
||||
name = 'featuresFolders'
|
||||
assert n1._cmdVars[name + 'Value'] == value
|
||||
|
||||
|
||||
def test_formatting_strings():
|
||||
graph = Graph('')
|
||||
n1 = graph.addNewNode('ImageMatching')
|
||||
name = 'weights'
|
||||
assert n1._cmdVars[name + 'Value'] == '""' # Empty string should generate empty quotes
|
||||
name = 'method'
|
||||
assert n1._cmdVars[name + 'Value'] == '"SequentialAndVocabularyTree"'
|
||||
|
||||
n2 = graph.addNewNode('ImageMatching')
|
||||
n2._buildCmdVars() # prepare vars for command line creation
|
||||
name = 'featuresFolders'
|
||||
assert n2._cmdVars[name + 'Value'] == '' # Empty list should become fully empty
|
||||
n2.featuresFolders.extend('')
|
||||
n2._buildCmdVars() # prepare vars for command line creation
|
||||
assert n2._cmdVars[name + 'Value'] == '""' # A list with one empty string should generate empty quotes
|
||||
n2.featuresFolders.extend('')
|
||||
n2._buildCmdVars() # prepare vars for command line creation
|
||||
assert n2._cmdVars[name + 'Value'] == '"" ""' # A list with 2 empty strings should generate quotes
|
||||
|
||||
|
||||
def test_formatting_groups():
|
||||
graph = Graph('')
|
||||
n3 = graph.addNewNode('ImageProcessing')
|
||||
n3._buildCmdVars() # prepare vars for command line creation
|
||||
name = 'sharpenFilter'
|
||||
assert n3._cmdVars[name + 'Value'] == 'False:3:1.0:0.0'
|
||||
name = 'fillHoles'
|
||||
assert n3._cmdVars[name + 'Value'] == 'False' # Booleans
|
||||
name = 'noiseFilter'
|
||||
assert n3._cmdVars[name + 'Value'] == 'False:"uniform":0.0:1.0:True'
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue