"""Module used for creation of manifest files."""
import collections
import os
import oyaml as yaml
[docs]
class ManifestWriter:
"""Tool for automated creation of manifest files.
Attributes
----------
manifest_dict: :class:`str`
Ordered dict that is filled with information and finally saved as
a manifest file.
version: :class:`str`
Version number of the manifest file format shown in the manifest file
type: :class:`str`
File type of the manifest file as displayed in the manifest file
file_format: :class:`str`
File format of the dataset data displayed in the manifest file
complete: :class:`bool`
Indication whether the data of the dataset are complete.
Sometimes, measurements get cancelled, but the data measured so far
are still useful. However, in such cases some of the metadata may
not fit to the actual dimensions of the numerical data.
metadata_extensions: :class:`list`
Extensions of metadata files
checksum_name: :class:`str`
Name used for checksum files covering all files of a dataset
checksum_data_name: :class:`str`
Name used for checksum files covering only the data of a dataset
manifest_name: :class:`str`
Name of the manifest file
extension_catalogue: :class:`dict`
File extensions and their description to be included in the manifest
"""
def __init__(self):
self.manifest_dict = collections.OrderedDict()
self.version = "0.1.0.dev1"
self.type = "datasafe dataset manifest"
self.file_format = "Bruker BES3T"
self.complete = True
self.metadata_extensions = [".info"]
self.checksum_name = None
self.checksum_data_name = None
self.manifest_name = None
self.extension_catalogue = {".DTA": "Bruker BES3T",
".DSC": "Bruker BES3T",
".info": "cwEPR Info File"}
[docs]
def write(self, path="", loi=""):
"""Create manifest file in target directory.
Parameters
----------
path: :class: `str`
path used for listing relevant files and for saving the manifest
file
loi: :class: `str`
loi that is inserted in the file
"""
self.manifest_dict = self._make_basic_dict()
self.manifest_dict["format"]["type"] = self.type
self.manifest_dict["format"]["version"] = self.version
self.manifest_dict["dataset"]["loi"] = loi
self.manifest_dict["dataset"]["format"] = self.file_format
self.manifest_dict["dataset"]["complete"] = self.complete
files_present = os.listdir(path)
for file in files_present:
if file in (self.checksum_name, self.checksum_data_name):
self._add_checksum_to_dict(file)
else:
self._add_file_to_dict(file)
self._write_to_file(path)
return self.manifest_dict
@staticmethod
def _make_basic_dict():
"""Create basic structure for the manifest dict."""
manifest_dict = collections.OrderedDict()
manifest_dict["format"] = collections.OrderedDict()
manifest_dict["dataset"] = collections.OrderedDict()
manifest_dict["files"] = collections.OrderedDict()
manifest_dict["files"]["metadata"] = list()
manifest_dict["files"]["data"] = list()
manifest_dict["files"]["checksums"] = list()
return manifest_dict
def _add_checksum_to_dict(self, file):
"""Add checksum file with information to the manifest dict.
Parameters
----------
file: :class: `str`
name of the file
"""
file_info = collections.OrderedDict()
file_info["name"] = file
file_info["format"] = "MD5 Checksum"
if file == self.checksum_data_name:
file_info["span"] = "Data"
else:
file_info["span"] = "Data, Metadata"
self.manifest_dict["files"]["checksums"].append(file_info)
def _add_file_to_dict(self, file):
"""Add file with information to the manifest dict.
Metadata files are automatically recognized as such.
Parameters
----------
file: :class: `str`
name of the file
"""
extension = "." + file.split(".")[1]
file_info_dict = dict()
file_info_dict["name"] = file
try:
file_info_dict["format"] = self.extension_catalogue[extension]
except KeyError:
file_info_dict["format"] = "unknown"
if extension in self.metadata_extensions:
self.manifest_dict["files"]["metadata"].append(file_info_dict)
else:
self.manifest_dict["files"]["data"].append(file_info_dict)
def _write_to_file(self, path=""):
"""Write manifest dict to file.
Parameters
----------
path: :class: `str`
target directory for the created file
"""
complete_filename = os.path.join(path, self.manifest_name)
with open(complete_filename, "w") as opened_file:
yaml.dump(self.manifest_dict, opened_file,
default_flow_style=False)
[docs]
def set_properties(self, datasafe=None):
"""Apply properties from a datasafe object.
Parameters
----------
datasafe: :class: `labinform.datasafe.Datasafe`
datasafe object from which to get properties.
"""
self.manifest_name = datasafe.manifest_name
self.checksum_data_name = datasafe.checksum_data_name
self.checksum_name = datasafe.checksum_name