Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract more metadata using exifTool #2645

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions meshroom/nodes/aliceVision/ExtractMetadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
__version__ = "0.1"

from meshroom.core import desc
from meshroom.core.utils import VERBOSE_LEVEL

import distutils.dir_util as du
import shutil
import glob
import os


class ExtractMetadata(desc.Node):
size = desc.DynamicNodeSize("input")

category = 'Utils'
documentation = '''
Using exifTool, this node extracts metadata of all images referenced in a sfmData and store them in appropriate files.
'''

inputs = [
desc.File(
name="input",
label="Input",
description="SfMData file input.",
value="",
),
desc.BoolParam(
name="keepFilename",
label="Keep Filename",
description="Keep the filename of the inputs for the outputs.",
value=False,
),
desc.ChoiceParam(
name="extension",
label="Output File Extension",
description="Metadata file extension.",
value="txt",
values=["txt", "xml", "xmp"],
exclusive=True,
),
desc.StringParam(
name="arguments",
label="Arguments",
description="ExifTool command arguments",
value="",
),
desc.ChoiceParam(
name="verboseLevel",
label="Verbose Level",
description="Verbosity level (fatal, error, warning, info, debug, trace).",
values=VERBOSE_LEVEL,
value="info",
),
]

outputs = [
desc.File(
name="output",
label="Result Folder",
description="Output path for the resulting images.",
value=desc.Node.internalFolder,
),
]

def resolvedPaths(self, inputSfm, outDir, keepFilename, extension):
import pyalicevision as av
from pathlib import Path

Check warning on line 67 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L66-L67

Added lines #L66 - L67 were not covered by tests

paths = {}
dataAV = av.sfmData.SfMData()
if av.sfmDataIO.load(dataAV, inputSfm, av.sfmDataIO.ALL) and os.path.isdir(outDir):
views = dataAV.getViews()
for id, v in views.items():
inputFile = v.getImage().getImagePath()
if keepFilename:
outputMetadata = os.path.join(outDir, Path(inputFile).stem + "." + extension)

Check warning on line 76 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L69-L76

Added lines #L69 - L76 were not covered by tests
else:
outputMetadata = os.path.join(outDir, str(id) + "." + extension)
paths[inputFile] = outputMetadata

Check warning on line 79 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L78-L79

Added lines #L78 - L79 were not covered by tests

return paths

Check warning on line 81 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L81

Added line #L81 was not covered by tests

def processChunk(self, chunk):
try:
chunk.logManager.start(chunk.node.verboseLevel.value)

Check warning on line 85 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L84-L85

Added lines #L84 - L85 were not covered by tests

if not chunk.node.input:
chunk.logger.warning('No image file to process')
return

Check warning on line 89 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L87-L89

Added lines #L87 - L89 were not covered by tests

outFiles = self.resolvedPaths(chunk.node.input.value, chunk.node.output.value, chunk.node.keepFilename.value, chunk.node.extension.value)

Check warning on line 91 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L91

Added line #L91 was not covered by tests

if not outFiles:
error = 'ExtractMetadata: input files listed, but no metadata to extract'
chunk.logger.error(error)
chunk.logger.info('Listed input files: {}'.format([i.value for i in chunk.node.inputFiles.value]))
raise RuntimeError(error)

Check warning on line 97 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L93-L97

Added lines #L93 - L97 were not covered by tests

if not os.path.exists(chunk.node.output.value):
os.mkdir(chunk.node.output.value)

Check warning on line 100 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L99-L100

Added lines #L99 - L100 were not covered by tests

for iFile, oFile in outFiles.items():
if chunk.node.extension.value == 'txt':
cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + iFile + ' > ' + oFile
elif chunk.node.extension.value == 'xml':
cmd = 'exiftool -X ' + chunk.node.arguments.value.strip() + ' ' + iFile + ' > ' + oFile

Check warning on line 106 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L102-L106

Added lines #L102 - L106 were not covered by tests
else: #xmp
cmd = 'exiftool -tagsfromfile ' + iFile + ' ' + chunk.node.arguments.value.strip() + ' ' + oFile
chunk.logger.debug(cmd)
os.system(cmd)

Check failure on line 110 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

codefactor.io / CodeFactor

meshroom/nodes/aliceVision/ExtractMetadata.py#L110

Starting a process with a shell, possible injection detected, security issue. (B605)
if not os.path.exists(oFile):
info = 'No metadata extracted for file ' + iFile
chunk.logger.info(info)

Check warning on line 113 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L108-L113

Added lines #L108 - L113 were not covered by tests
else:
f = open(oFile)
if f.readline().find('command not found') != -1:
error = 'Metadata cannot be extracted, exiftool command not found'
chunk.logger.error(error)
raise RuntimeError(error)
f.close()
chunk.logger.info('Metadata extraction end')

Check warning on line 121 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L115-L121

Added lines #L115 - L121 were not covered by tests

finally:
chunk.logManager.end()

Check warning on line 124 in meshroom/nodes/aliceVision/ExtractMetadata.py

View check run for this annotation

Codecov / codecov/patch

meshroom/nodes/aliceVision/ExtractMetadata.py#L124

Added line #L124 was not covered by tests
Loading