Source code for ewoksid16a.tasks.common.masterfile
import os
import h5py
from ewokscore import Task
from silx.io import h5py_utils
from silx.io.url import DataUrl
DEFAULTS = {"resolve_links": True}
[docs]
class AddEntryToMasterfile(
Task,
input_names=["masterfile_uri", "output_root_uri"],
optional_input_names=["resolve_path"],
output_names=["masterfile_uri", "output_root_uri"],
):
"""
This task add or replace an entry in the masterfile
"""
def _resolve_h5_link(self, output_root_uri, already_visited=None):
if already_visited is None:
already_visited = []
output_root_uri_txt = (
output_root_uri.file_path() + "::" + output_root_uri.data_path()
)
if output_root_uri_txt in already_visited:
raise RuntimeError(
f"{output_root_uri} already visited, must have a circular linking issue!"
)
already_visited += [
output_root_uri_txt,
]
with h5py_utils.open_item(output_root_uri.file_path(), "/") as fd:
obj = fd.get(output_root_uri.data_path(), getlink=True)
if isinstance(obj, h5py.SoftLink):
linkval = obj.link
if not os.path.isabs(linkval):
linkval = obj.path.normpath(
os.path.join(output_root_uri.data_path(), linkval)
)
return self._resolve_h5_link(
DataUrl(output_root_uri.file_path() + "::" + linkval),
already_visited,
)
elif isinstance(obj, h5py.ExternalLink):
return self._resolve_h5_link(
DataUrl(obj.path + "::" + obj.link), already_visited
)
return output_root_uri
[docs]
def run(self):
pars = {**DEFAULTS, **self.get_input_values()}
muri = pars["masterfile_uri"].split("::")
ouri = pars["output_root_uri"].split("::")
masterfile_uri = DataUrl(file_path=muri[0], data_path=muri[1])
output_root_uri = DataUrl(file_path=ouri[0], data_path=ouri[1])
if pars["resolve_links"]:
output_root_uri = self._resolve_h5_link(output_root_uri)
relpath = os.path.relpath(
output_root_uri.file_path(), os.path.dirname(masterfile_uri.file_path())
)
with h5py.File(masterfile_uri.file_path(), "a") as fd:
if masterfile_uri.data_path() in fd:
del fd[masterfile_uri.data_path()]
fd[masterfile_uri.data_path()] = h5py.ExternalLink(
relpath, output_root_uri.data_path()
)
self.outputs["masterfile_uri"] = self.inputs["masterfile_uri"]
self.outputs["output_root_uri"] = self.inputs["output_root_uri"]