133 lines
5.7 KiB
Python
133 lines
5.7 KiB
Python
from datetime import datetime
|
|
import os
|
|
import shutil
|
|
import markdown
|
|
import frontmatter
|
|
from pathlib import Path
|
|
from logger import logger
|
|
from config import Config
|
|
from jinja_env import env, content_item_template, index_template
|
|
|
|
class DefaultFrontmatterHeader:
|
|
def __init__(self, title):
|
|
self.title = f"title: '{title}'\n"
|
|
self.date = f"date: '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}'\n"
|
|
self.omit_second_title = f"omit_second_title: '{str(False)}'\n"
|
|
self.description = "description: \n"
|
|
self.author = "author: \n"
|
|
|
|
class ContentItemPrototype:
|
|
def render_content(self):
|
|
logger.debug(f"Rendering {self.source_filename} to {Config.OUTPUT_DIR}/{self.target_filename}")
|
|
if self.image_file.exists():
|
|
shutil.copyfile(self.image_src_file, Path(Config.OUTPUT_DIR) / self.image)
|
|
if self.css_file.exists():
|
|
shutil.copyfile(self.custom_css_src_file,Path(Config.OUTPUT_DIR) / self.custom_css)
|
|
if self.js_file.exists():
|
|
shutil.copyfile(self.custom_js_src_file, Path(Config.OUTPUT_DIR) / self.custom_js)
|
|
with self.target_filename.open("w", encoding="utf-8") as f:
|
|
f.write(content_item_template.render(content_item = self, page_title = self.title))
|
|
|
|
def parse_content(self):
|
|
try:
|
|
self.source_filename = Path(self.source_filename)
|
|
self.subdir = self.source_filename.parent
|
|
logger.debug(f"Parsing item {self.source_filename}")
|
|
self.slug = self.source_filename.stem
|
|
self.target_filename = Path(f"{Config.OUTPUT_DIR}/{self.source_filename.parent}/{self.source_filename.stem}.html")
|
|
self.data = frontmatter.load(self.source_filename)
|
|
self.html = markdown.markdown(self.data.content)
|
|
self.url = "<a href=" + f"{self.subdir}/{self.slug}.html" + "> ...read more</a>"
|
|
self.preview = self.html[:300] + self.url
|
|
self.title = self.data.get("title", self.slug)
|
|
self.omit_second_title = self.data.get("omit_second_title", False)
|
|
self.date = self.data.get("date", "2000-01-01T00:00:00+03:00")
|
|
self.image_file = self.source_filename.stem + ".jpg"
|
|
self.css_file = self.source_filename.stem + ".css"
|
|
self.js_file = self.source_filename.stem + ".js"
|
|
except Exception as e:
|
|
logger.error(e)
|
|
|
|
def create_content(self):
|
|
with open(self.source_filename, mode="w", encoding="utf-8") as f:
|
|
f.writelines([
|
|
"---\n",
|
|
self.default_frontmatter_header.title,
|
|
self.default_frontmatter_header.date,
|
|
self.default_frontmatter_header.description,
|
|
self.default_frontmatter_header.author,
|
|
self.default_frontmatter_header.omit_second_title,
|
|
"---\n"
|
|
])
|
|
|
|
def __init__(self, filename, title = None):
|
|
self.source_filename = filename
|
|
self.title = title or self.source_filename.stem
|
|
self.default_frontmatter_header = DefaultFrontmatterHeader(self.title)
|
|
|
|
class SitePrototype:
|
|
def init_site():
|
|
logger.info("Initializing new site")
|
|
content_dir = Path(Config.CONTENT_DIR)
|
|
static_dir = Path(Config.STATIC_DIR)
|
|
templates_dir = Path(Config.TEMPLATES_DIR)
|
|
images_dir = Path(f"{Config.STATIC_DIR}/images")
|
|
css_dir = Path(f"{Config.STATIC_DIR}/css")
|
|
js_dir = Path(f"{Config.STATIC_DIR}/js")
|
|
# Create directories
|
|
for subdir in [content_dir, static_dir, templates_dir, images_dir, css_dir, js_dir]:
|
|
os.makedirs(subdir, exist_ok=True)
|
|
# Create templates from literals
|
|
import templates
|
|
template_names = [t for t in dir(templates) if not t.startswith('_')]
|
|
for template_name in template_names:
|
|
template_content = getattr(templates, template_name)
|
|
with open(templates_dir / f"{template_name}.html", "w", encoding="utf8") as f:
|
|
f.write(template_content)
|
|
# Create static/about.md
|
|
|
|
|
|
def build_site(self):
|
|
# Recreate the output dir if needed
|
|
if output_dir.exists():
|
|
shutil.rmtree(output_dir)
|
|
output_dir.mkdir()
|
|
|
|
# Create public subdirs
|
|
subdirs = [img_dir, css_dir, js_dir]
|
|
for subdir in subdirs:
|
|
subdir.mkdir(arents=True, exist_ok=True)
|
|
|
|
# Copy static files if exist
|
|
if static_dir.exists():
|
|
shutil.copytree(static_dir, output_dir / "static", dirs_exist_ok=True)
|
|
|
|
# Parse the content files
|
|
content_items = []
|
|
for md_file in content_dir.glob("*.md"):
|
|
current_content_item = ContentItemPrototype(md_file)
|
|
current_content_item.render_content()
|
|
content_items.append({
|
|
"slug": current_content_item.slug,
|
|
"title": current_content_item.title,
|
|
"date": current_content_item.date,
|
|
# "preview": markdown.markdown(current_content_item.preview),
|
|
"image": current_content_item.image,
|
|
})
|
|
|
|
# Render the index file
|
|
with (output_dir / "index.html").open("w", encoding="utf-8") as f:
|
|
f.write(index_template.render(page_title = Config.MAIN_PAGE_TITLE, content_items=content_items))
|
|
|
|
# Render the about file
|
|
about_content = ContentItemPrototype(Path('static/about.md'))
|
|
about_content.render_content()
|
|
|
|
# Move 'robots.txt' into output_dir
|
|
shutil.copyfile(static_dir / 'robots.txt', output_dir / 'robots.txt')
|
|
|
|
logger.info(f"Created {len(content_items)} content items.")
|
|
|
|
def __init__(self):
|
|
self.output_dir = Path(Config.OUTPUT_DIR)
|
|
|