summaryrefslogtreecommitdiff
path: root/src/pyssg/builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pyssg/builder.py')
-rw-r--r--src/pyssg/builder.py100
1 files changed, 72 insertions, 28 deletions
diff --git a/src/pyssg/builder.py b/src/pyssg/builder.py
index 391c7e0..eec0125 100644
--- a/src/pyssg/builder.py
+++ b/src/pyssg/builder.py
@@ -1,4 +1,6 @@
import os
+import sys
+import pprint
from copy import deepcopy
from operator import itemgetter
from logging import Logger, getLogger
@@ -15,10 +17,33 @@ log: Logger = getLogger(__name__)
class Builder:
def __init__(self, config: dict,
- db: Database):
+ db: Database,
+ dir_path: str) -> None:
log.debug('initializing site builder')
self.config: dict = config
self.db: Database = db
+ self.dir_path: str = dir_path
+
+ if self.dir_path not in self.config['dirs']:
+ log.error('couldn\'t find "dirs.%s" attribute in config file', self.dir_path)
+ sys.exit(1)
+
+ if os.path.isabs(self.dir_path) and self.dir_path.strip() != '/':
+ log.error('dir path "%s" cannot be absolute, except for the special case "/"', self.dir_path)
+ sys.exit(1)
+
+ log.debug('building dir_config and src/dst paths for "%s" dir path', self.dir_path)
+ self.dir_config: dict = deepcopy(self.config['dirs'][self.dir_path])
+
+ if self.dir_path.strip() == '/':
+ log.debug('dir path is "/", copying src/dst directly')
+ self.dir_config['src'] = self.config['path']['src']
+ self.dir_config['dst'] = self.config['path']['dst']
+ self.dir_config['url'] = self.config['url']['main']
+ else:
+ self.dir_config['src'] = os.path.join(self.config['path']['src'], self.dir_path)
+ self.dir_config['dst'] = os.path.join(self.config['path']['dst'], self.dir_path)
+ self.dir_config['url'] = f"{self.config['url']['main']}/{self.dir_path}"
# the autoescape option could be a security risk if used in a dynamic
# website, as far as i can tell
@@ -41,21 +66,29 @@ class Builder:
def build(self) -> None:
- log.debug('building site')
- self.dirs = get_dir_structure(self.config['path']['src'],
- ['templates'])
- self.md_files = get_file_list(self.config['path']['src'],
+ log.debug('building site for dir path "%s"', self.dir_path)
+ if 'exclude_dirs' not in self.dir_config:
+ log.debug('"exclude_dirs" attribute not found in "dirs.%s" in config file', self.dir_path)
+ self.dir_config['exclude_dirs'] = []
+ if not isinstance(self.dir_config['exclude_dirs'], list):
+ log.error('"exclude_dirs" attribute is not of type "list"')
+ sys.exit(1)
+
+ self.dirs = get_dir_structure(self.dir_config['src'],
+ self.dir_config['exclude_dirs'])
+ self.md_files = get_file_list(self.dir_config['src'],
['.md'],
- ['templates'])
- self.html_files = get_file_list(self.config['path']['src'],
+ self.dir_config['exclude_dirs'])
+ self.html_files = get_file_list(self.dir_config['src'],
['.html'],
- ['templates'])
+ self.dir_config['exclude_dirs'])
self.__create_dir_structure()
self.__copy_html_files()
parser: MDParser = MDParser(self.md_files,
self.config,
+ self.dir_config,
self.db)
parser.parse_files()
@@ -67,23 +100,35 @@ class Builder:
# dict for the keyword args to pass to the template renderer
log.debug('adding config, all_pages and all_tags to exposed vars for jinja')
self.common_vars = dict(config=self.config,
+ dir_config=self.dir_config,
all_pages=self.all_files,
all_tags=self.all_tags)
- self.__render_articles()
- self.__render_tags()
- self.__render_template('index.html', 'index.html', **self.common_vars)
- self.__render_template('rss.xml', 'rss.xml', **self.common_vars)
- self.__render_template('sitemap.xml', 'sitemap.xml', **self.common_vars)
+ self.__render_pages(self.dir_config['plt'])
+
+ if 'tags' in self.dir_config and self.dir_config['tags']:
+ log.debug('rendering tags for dir "%s"', self.dir_path)
+ create_dir(os.path.join(self.dir_config['dst'], 'tag'), True, True)
+ self.__render_tags(self.dir_config['tags'])
+
+ opt_renders: dict[str, str] = {'index': 'index.html',
+ 'rss': 'rss.xml',
+ 'sitemap': 'sitemap.xml'}
+ for opt in opt_renders.keys():
+ if opt in self.dir_config and self.dir_config[opt]:
+ self.__render_template(self.dir_config[opt],
+ opt_renders[opt],
+ **self.common_vars)
def __create_dir_structure(self) -> None:
log.debug('creating dir structure')
- dir_path: str
+ create_dir(self.dir_config['dst'], True, True)
+ _dir_path: str
for d in self.dirs:
- dir_path = os.path.join(self.config['path']['dst'], d)
+ _dir_path = os.path.join(self.dir_config['dst'], d)
# using silent=True to not print the info create dir msgs for this
- create_dir(dir_path, True, True)
+ create_dir(_dir_path, True, True)
def __copy_html_files(self) -> None:
@@ -95,15 +140,14 @@ class Builder:
dst_file: str
for f in self.html_files:
- src_file = os.path.join(self.config['path']['src'], f)
- dst_file = os.path.join(self.config['path']['dst'], f)
+ src_file = os.path.join(self.dir_config['src'], f)
+ dst_file = os.path.join(self.dir_config['dst'], f)
# only copy files if they have been modified (or are new)
- if self.db.update(src_file, remove=f'{self.config["path"]["src"]}/'):
+ if self.db.update(src_file, remove=f'{self.dir_config["src"]}/'):
log.debug('file "%s" has been modified or is new, copying', f)
copy_file(src_file, dst_file)
else:
- # TODO: need to check if this holds after yaml update
if self.config['info']['force']:
log.debug('file "%s" hasn\'t been modified, but option force is set to true, copying anyways', f)
copy_file(src_file, dst_file)
@@ -111,9 +155,9 @@ class Builder:
log.debug('file "%s" hasn\'t been modified, ignoring', f)
- def __render_articles(self) -> None:
+ def __render_pages(self, template_name: str) -> None:
log.debug('rendering html')
- article_vars: dict = deepcopy(self.common_vars)
+ page_vars: dict = deepcopy(self.common_vars)
temp_files: list[Page]
# check if only updated should be created
@@ -126,14 +170,14 @@ class Builder:
for p in temp_files:
log.debug('adding page to exposed vars for jinja')
- article_vars['page'] = p
+ page_vars['page'] = p
# actually render article
- self.__render_template("page.html",
+ self.__render_template(template_name,
p.name.replace('.md','.html'),
- **article_vars)
+ **page_vars)
- def __render_tags(self) -> None:
+ def __render_tags(self, template_name: str) -> None:
log.debug('rendering tags')
tag_vars: dict = deepcopy(self.common_vars)
tag_pages: list[Page]
@@ -154,7 +198,7 @@ class Builder:
tag_vars['tag_pages'] = tag_pages
# actually render tag page
- self.__render_template('tag.html',
+ self.__render_template(template_name,
f'tag/@{t[0]}.html',
**tag_vars)
@@ -166,7 +210,7 @@ class Builder:
file_name, template_name)
template: Template = self.env.get_template(template_name)
content: str = template.render(**template_vars)
- dst_path: str = os.path.join(self.config['path']['dst'], file_name)
+ dst_path: str = os.path.join(self.dir_config['dst'], file_name)
log.debug('writing html file to path "%s"', dst_path)
with open(dst_path, 'w') as f: