"""
The manifest comprises course metadata.
A :file:`manifest.yml` file needs to exist in every course content and resides
at the content root directory.
There is also a representation in JSON format. It is generated automatically
by the extension
:class:`WriteManifest <innoconv.ext.write_manifest.WriteManifest>`
and copied to the output folder.
Other extensions may add custom fields to the output manifest by implementing
a method :py:meth:`manifest_fields`. It needs to return a :any:`dict` that
is merged into the manifest.
A :file:`manifest.yml` is written by course authors while the
:file:`manifest.json` is generated by the converter and used by
innoconv-compatible viewers. The included information for both versions differ.
Example
=======
.. code-block:: yaml
title:
en: Example title
de: Beispiel-Titel
languages: en,de
"""
import os
import yaml
from innoconv.constants import MANIFEST_BASENAME
[docs]class Manifest:
"""Represents course metadata."""
required_fields = ("title", "languages")
optional_fields = ("keywords", "license")
def __init__(self, data):
"""
Initialize a manifest.
:param data: A dict with the manifest fields as keys
:type data: dict
"""
for field in self.required_fields:
if field not in data:
msg = "Required field {} not found in manifest!".format(field)
raise RuntimeError(msg)
for key, value in data.items():
setattr(self, key, value)
[docs] @classmethod
def from_directory(cls, dirpath):
"""
Read manifest from content directory.
:param dirpath: Full path to content directory.
:type dirpath: str
:rtype: Manifest
:returns: Manifest object
"""
def _read_manifest_data(file_ext):
filename = "{}.{}".format(MANIFEST_BASENAME, file_ext)
with open(os.path.join(dirpath, filename), "r") as file:
return file.read()
try:
manifest_data = _read_manifest_data("yml")
except FileNotFoundError:
manifest_data = _read_manifest_data("yaml")
return cls.from_yaml(manifest_data)
[docs] @classmethod
def from_yaml(cls, yaml_data):
"""
Create a manifest from YAML data.
:param yaml_data: YAML representation of a manifest
:type yaml_data: str
:rtype: Manifest
:returns: Manifest object
"""
data = yaml.safe_load(yaml_data)
return Manifest(data)