static site generator part 2 --- config and other fixes
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
parent
0d59e64323
commit
1ace0e1427
@ -9,6 +9,7 @@ import os
|
||||
from logging.config import dictConfig
|
||||
|
||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
from termcolor import cprint
|
||||
|
||||
from incorporealcms.config import Config
|
||||
|
||||
@ -24,7 +25,9 @@ def init_instance(instance_path: str, test_config: dict = None):
|
||||
instance_config = os.path.join(instance_path, 'config.json')
|
||||
if os.path.isfile(instance_config):
|
||||
with open(instance_config, 'r') as config:
|
||||
Config.update(json.load(config))
|
||||
config_dict = json.load(config)
|
||||
cprint(f"splicing {config_dict} into the config", 'yellow')
|
||||
Config.update(config_dict)
|
||||
|
||||
if test_config:
|
||||
Config.update(test_config)
|
||||
|
@ -51,8 +51,6 @@ class Config(object):
|
||||
},
|
||||
}
|
||||
|
||||
MEDIA_DIR = 'media'
|
||||
|
||||
# customizations
|
||||
PAGE_STYLES = {
|
||||
'dark': '/static/css/dark.css',
|
||||
|
@ -46,69 +46,12 @@ def handle_markdown_file_path(path: str) -> str:
|
||||
image=get_meta_str(md, 'image'),
|
||||
content=content,
|
||||
user_style=Config.PAGE_STYLES.get(Config.DEFAULT_PAGE_STYLE),
|
||||
base_url=Config.BASE_HOST, navs=parent_navs,
|
||||
base_url=Config.BASE_HOST + instance_resource_path_to_request_path(path),
|
||||
navs=parent_navs,
|
||||
mtime=mtime.strftime('%Y-%m-%d %H:%M:%S %Z'),
|
||||
extra_footer=extra_footer)
|
||||
|
||||
|
||||
def request_path_to_instance_resource_path(path):
|
||||
"""Turn a request URL path to the full page path.
|
||||
|
||||
flask.Flask.open_instance_resource will open a file like /etc/hosts if you tell it to,
|
||||
which sucks, so we do a lot of work here to make sure we have a valid request to
|
||||
something inside the pages dir.
|
||||
"""
|
||||
# check if the path is allowed
|
||||
base_dir = os.path.realpath(f'{app.instance_path}/pages/')
|
||||
safe_path = safe_join(base_dir, path)
|
||||
# bail if the requested real path isn't inside the base directory
|
||||
if not safe_path:
|
||||
logger.warning("client tried to request a path '%s' outside of the base_dir!", path)
|
||||
raise PermissionError
|
||||
|
||||
verbatim_path = os.path.abspath(safe_path)
|
||||
resolved_path = os.path.realpath(verbatim_path)
|
||||
logger.debug("base_dir '%s', constructed resolved_path '%s' for path '%s'", base_dir, resolved_path, path)
|
||||
|
||||
# see if we have a real file or if we should infer markdown rendering
|
||||
if os.path.exists(resolved_path):
|
||||
# if this is a file-like request but actually a directory, redirect the user
|
||||
if os.path.isdir(resolved_path) and not path.endswith('/'):
|
||||
logger.info("client requested a path '%s' that is actually a directory", path)
|
||||
raise IsADirectoryError
|
||||
|
||||
# if the requested path contains a symlink, redirect the user
|
||||
if verbatim_path != resolved_path:
|
||||
logger.info("client requested a path '%s' that is actually a symlink to file '%s'", path, resolved_path)
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'symlink'
|
||||
|
||||
# derive the proper markdown or actual file depending on if this is a dir or file
|
||||
if os.path.isdir(resolved_path):
|
||||
resolved_path = os.path.join(resolved_path, 'index.md')
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'markdown'
|
||||
|
||||
logger.info("final DIRECT path = '%s' for request '%s'", resolved_path, path)
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'file'
|
||||
|
||||
# if we're here, this isn't direct file access, so try markdown inference
|
||||
verbatim_path = f'{safe_path}.md'
|
||||
resolved_path = os.path.realpath(verbatim_path)
|
||||
|
||||
# does the final file actually exist?
|
||||
if not os.path.exists(resolved_path):
|
||||
logger.warning("requested final path '%s' does not exist!", resolved_path)
|
||||
raise FileNotFoundError
|
||||
|
||||
# check for symlinks
|
||||
if verbatim_path != resolved_path:
|
||||
logger.info("client requested a path '%s' that is actually a symlink to file '%s'", path, resolved_path)
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'symlink'
|
||||
|
||||
logger.info("final path = '%s' for request '%s'", resolved_path, path)
|
||||
# we checked that the file exists via absolute path, but now we need to give the path relative to instance dir
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), 'markdown'
|
||||
|
||||
|
||||
def generate_parent_navs(path):
|
||||
"""Create a series of paths/links to navigate up from the given resource path."""
|
||||
if path == 'index.md':
|
||||
|
@ -26,11 +26,13 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
{% if not loop.last %} » {% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if page_styles %}
|
||||
<div class="styles">
|
||||
{% for style in page_styles %}
|
||||
<a href="?style={{ style }}">[{{ style }}]</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user