import os from distutils.dir_util import copy_tree from pathlib import Path, PurePath import argparse from pyramid.paster import bootstrap from pyramid.scripts.common import parse_vars from pyramid.path import AssetResolver from pyramid.request import Request from flatfilecms.models import Folder, Document class Renderer: def __init__(self, b, dest): self.app = b["app"] self.root = b["root"] self.request = b["request"] self.dest = dest def render_folder(self, folder=None, path=PurePath("")): if folder is None: folder = self.root for k, v in folder.items(): new_path = path / k if isinstance(v, Folder): (self.dest / new_path).mkdir(exist_ok=True) self.render_folder(v, new_path) elif isinstance(v, Document): url = str(path / k) if k == "index": new_path = new_path.with_suffix(".html") url = str(path) if path != PurePath("") else "/" elif len(new_path.suffix) == 0: (self.dest / new_path).mkdir(exist_ok=True) new_path = new_path / "index.html" print("Generating {}".format(url)) with (self.dest / new_path).open("wb") as f: request = Request.blank(url) f.write(request.get_response(self.app).body) def WritableDirectory(value): p = Path(value) if not p.exists(): p.mkdir() return p if not p.is_dir(): raise argparse.ArgumentTypeError("{0} is not a directory".format(p)) if os.access(p, os.W_OK): return p else: raise argparse.ArgumentTypeError("{0} is not a writable directory".format(p)) def main(): parser = argparse.ArgumentParser(description="Generate static pages.") parser.add_argument( "-c", "--config", help="use configuration file " "like production.ini or development.ini", required=True, ) parser.add_argument( "path", help="where to store generated files", type=WritableDirectory ) parser.add_argument( "-o", "--options", nargs="*", default={}, type=parse_vars, help="additional options in form OPTION=VALUE", ) args = parser.parse_args() b = bootstrap(args.config, **args.options) introspector = b["registry"].introspector a = AssetResolver() for v in introspector.get_category("static views"): print("Copying static dir {}".format(v["introspectable"]["name"])) p = a.resolve(v["introspectable"]["spec"]).abspath() copy_tree(str(p), str(args.path / v["introspectable"]["name"])) r = Renderer(b, args.path) r.render_folder()