Source code for innoconv.runner

"""Runner module"""

import json
from os import makedirs, walk
from os.path import abspath, dirname, isdir, join, sep, split

from innoconv.constants import (
    CONTENT_FILENAME, OUTPUT_CONTENT_FILENAME, MANIFEST_FILENAME, TOC_FILENAME)
from innoconv.utils import to_ast, log


[docs]def splitall(path): """Split path into directory components.""" all_parts = [] while 1: parts = split(path) if parts[1] == path: all_parts.insert(0, parts[1]) break else: path = parts[0] all_parts.insert(0, parts[1]) return all_parts
[docs]class InnoconvRunner(): """innoConv runner. It walks over a directory tree and converts content files to JSON. """ def __init__(self, source_dir, output_dir_base, languages, debug=False): self.source_dir = source_dir self.output_dir_base = output_dir_base self.languages = languages self._manifest = {} self._toc = None if debug: self._log = log else: self._log = lambda *args: None
[docs] def run(self): """Start the conversion. Iterate over language folders. """ for language in self.languages: self._convert_folder(language)
def _convert_folder(self, language): """Convert a language folder.""" path = abspath(join(self.source_dir, language)) if not isdir(path): raise RuntimeError( "Error: Directory {} does not exist".format(path)) self._toc = [] for root, dirs, files in walk(path): # note: all dirs manipulation must happen in-place! for i, directory in enumerate(dirs): if directory.startswith('_'): del dirs[i] # skip meta directories like '_static' dirs.sort() # sort section names # process content file if CONTENT_FILENAME in files: filepath = join(root, CONTENT_FILENAME) self._process_file(filepath) else: raise RuntimeError( "Found section without content file: {}".format(root)) self._write_toc(language) self._write_manifest(language) def _write_toc(self, language): filepath = join(self.output_dir_base, language, TOC_FILENAME) self._write_json_file( filepath, self._toc, "Wrote TOC: {}".format(filepath)) def _write_manifest(self, language): filepath = join(self.output_dir_base, language, MANIFEST_FILENAME) self._write_json_file( filepath, self._manifest, "Wrote manifest: {}".format(filepath)) def _add_to_toc(self, dirpath, title): path_components = splitall(dirpath) path_components.pop(0) # language if not path_components: # this is the root section self._manifest['title'] = title return children = self._toc while path_components: section_id = path_components.pop(0) # find/create child leaf found = None for child in children: if child['id'] == section_id: found = child try: children = child['children'] except KeyError: children = child['children'] = [] break # arrived at leaf -> add section if not found: children.append({ 'id': section_id, 'title': title, }) def _process_file(self, filepath): ast, title = to_ast(filepath) # save content file rel_path = dirname(filepath.replace(self.source_dir, '').lstrip(sep)) filepath_out = join( self.output_dir_base, rel_path, OUTPUT_CONTENT_FILENAME) makedirs(dirname(filepath_out), exist_ok=True) self._write_json_file( filepath_out, ast, "Wrote {}".format(filepath_out)) # add to TOC self._add_to_toc(rel_path, title) return title def _write_json_file(self, filepath, data, msg): with open(filepath, 'w') as out_file: json.dump(data, out_file) self._log(msg)